About
Pierre is a seasoned front-end web developer and content project manager with extensive expertise in user experience. Excels at creating intuitive and engaging interfaces, leveraging the latest tools, and ensuring that Section 508 compliance adheres to industry standards.
If you can design it, I can code it.
Delivers exceptional user experiences that meet and exceed expectations. Provides innovative solutions tailored to meet the evolving needs of users and stakeholders alike. Relishes solving problems creatively in a fast-paced environment, consistently meeting deadlines and getting results.
Code
/*
This JavaScript code is useful for
creating accordion menus that are
both accessible & usable by
providing focus to the current
item selected.
*/
// document ready
$(function() {
// cache objects
const mainNavLinks = $('header').find('.main-nav > ul').children('li');
const acc = $('main').find('.accordion');
// target main nav link clicked
$(mainNavLinks).on('click', 'a', function(){
$('.main-nav a').removeClass('current');
$(this).addClass('current');
});
// show only the first panel (by default)
$(acc).find('button').first().addClass('active');
$(acc).find('.panel').not(':first').attr('hidden', 'hidden').hide();
// update aria-expanded
$(acc).find('button').not(':first').attr('aria-expanded', 'false');
// on click event
$(acc).find('h3').on('click', 'button', function(){
// close all other panels
let otherButtons = $(acc).find('button').not(this);
$(otherButtons).removeClass('active').parent().next().slideUp(400, function() {
toggleExpanded($(this));
toggleHidden($(this));
});
// open current panel selected
$(this).toggleClass('active').parent().next().slideToggle(400, function() {
toggleExpanded($(this));
toggleHidden($(this));
focusActiveItem($(this));
});
});
}); // end ready
// functions
// toggle aria-expanded based on panel visibility
function toggleExpanded(elm){
$(elm).prev('h3').children('button').attr('aria-expanded', $(elm).is(':visible'));
} // end func
// toggle hidden based on panel visibility
function toggleHidden(elm){
$(elm).css('display')==='none' ? $(elm).attr('hidden', 'hidden') : $(elm).removeAttr('hidden');
} // end func
// scroll to target
function smoothScrollingTo(target) {
const root = $('html, body');
$(root).stop().animate({ scrollTop: $(target).offset().top - 10 }, 200);
} // end func
// shift focus to current active item
function focusActiveItem(elm){
const tgtCodeSect = $('main').find('section:nth-of-type(2)');
let allActiveBtns = $(tgtCodeSect).children('.accordion').find('button').hasClass('active'),
tgtActiveBtn = $(elm).prev('h3').children('button');
// if no items are active then scroll to top of code section
// else scroll to top of active item
!allActiveBtns ? smoothScrollingTo(tgtCodeSect) : smoothScrollingTo(tgtActiveBtn);
} // end func
/*
This styling code is useful for
overlaying text on top of
background images, which provides
an accessible solution when
combining text & graphics.
*/
/* site container */
:root {
--padding-inline: .5rem;
@media (min-width: 360px) { --padding-inline: 1rem; }
--info-spacing: 1rem;
}
body {
width: min(100% - (var(--padding-inline) * 2), 960px);
margin-inline: auto;
min-height: 100vh;
min-height: 100lvh; /* mobile optimized */
}
/* banner */
.banner { margin-top: var(--info-spacing); }
.banner > img,
.col-33-66 img { object-fit: cover; }
/* define grid columns */
[class*="col-"] {
margin: 1.5em 0 .2142857em;
display: grid;
grid-template-columns: 1fr;
gap: 21px;
}
[class*="col-"] > div { height: 230px; }
/* limit column max width */
.col-33-66 > div:first-of-type,
.col-special > div:not(:first-of-type) { max-width: 306px; }
/* one-third two-third column layout */
.col-33-66 > div:last-of-type {
background-color: #024b82;
height: auto; /* mobile fix */
}
.col-33-66 p {
margin: var(--info-spacing);
font-weight: 700;
color: #fff;
}
/* three column layout */
.col-3 { grid-template-columns: repeat(auto-fit, minmax(0, 306px)); }
/* two-third one-third column special layout */
.col-special { margin-bottom: 1.25rem; }
.col-special > div:not(:first-of-type) { height: 105px; } /* height fix */
/* full column layout */
@media (min-width: 726px) {
/* one-third two-third column layout */
.col-33-66 { grid-template-columns: 306px 1fr; }
/* two-third one-third column special layout */
.col-special { grid: repeat(2, 105px) / 1fr 306px; }
.col-special > div:first-of-type { grid-area: 1 / 1 / 3 / 2; }
.col-special > div:nth-of-type(2) { grid-area: 1 / 2 / 2 / 3; }
.col-special > div:nth-of-type(3) { grid-area: 2 / 2 / 3 / 3; }
}
/* overlap all content */
.col-3 > div,
.col-special > div {
display: grid;
> * { grid-area: 1 / 1; }
}
/* background images */
[class*="Txt"] {
height: 100%; /* fix */
display: block;
transition: all .4s ease-in-out;
z-index: 1; /* ensure text is above the image */
}
.infoTxt {
background: #40B5EA center no-repeat;
background-size: cover;
}
.graphic1 { background-image:url('../img/info_graphic1.jpg'); }
.graphic2 { background-image:url('../img/info_graphic2.jpg'); }
.graphic3 { background-image:url('../img/info_graphic3.jpg'); }
.graphic4 { background-image:url('../img/info_graphic4.jpg'); }
.graphic5 { background-image:url('../img/info_graphic5.jpg'); }
.graphic6 { background-image:url('../img/info_graphic6.jpg'); }
.three { background-color: #3CB87A; }
.faq, .contact { background-color: #468BCC; }
[class*="Txt"]:hover,
[class*="Txt"]:focus-within { filter: saturate(150%); }
/* overlay text */
[class*="Txt"] > h2 {
margin: 0 var(--info-spacing);
font-size: clamp(1.2rem, 3.75vw, 1.4rem);
line-height: 1.25;
text-transform: uppercase;
text-shadow: 2px 2px 4px rgba(0,0,0,0.7);
color: #fff;
}
[class*="Txt"] > h2 + h2 { margin-top: var(--info-spacing); } /* add top space to next h2 sibling */
/* use display flexbox */
[class*="flex-"] { display: flex; }
/* place text (bottom left corner) */
.flex-btmLeft {
flex-direction: column;
justify-content: flex-end;
}
.flex-btmLeft > :last-child { margin-bottom: var(--info-spacing); } /* add bottom space to last child ONLY */
/*
This JavaScript code is useful for
mobile display by utilizing a
fully accessible off-canvas menu
to toggle the hamburger style menu
(can also toggle w/ the escape
key). This code also resets the
off-canvas menu (when switching
out of mobile view).
*/
// document ready
$(function() {
// add class .js if JS is enabled
$('html').first().removeClass('no-js').addClass('js');
// cache menu objects
const menuLink = $('header[role="banner"]').find('button'),
bod = $('body');
// set up the click behavior
menuLink.on('click', function(){
toggleExpanded($(this));
toggleNav($(this), bod);
});
// toggle hamburger menu & body w/ escape key
function toggleHandler(e){
if(e.keyCode == 27){
toggleExpanded(menuLink);
toggleNav(menuLink, bod);
}
}
// check for smaller screen width
function checkSmallScreen(){
const mq = window.matchMedia("(max-width: 767px)");
mq.matches ? $(document).on('keyup', toggleHandler) : $(document).off('keyup');
}
checkSmallScreen();
$(window).resize(checkSmallScreen);
// reset the hamburger menu (when switching from mobile to tablet/desktop view)
$(window).resize(function(){
var width = $(this).width();
if(width >= 768 && bod.hasClass('active')){
menuLink.add(bod).removeClass('active')
.end()
.prop('ariaExpanded', 'false')
.end()
.find('i').eq(0).removeClass('fa-times').addClass('fa-bars');
}
});
}); // end ready
// functions
// toggle aria-expanded
function toggleExpanded(elm){
$(elm).attr('aria-expanded', $(elm).attr('aria-expanded') == 'true' ? 'false' : 'true');
} // end func
// toggle hamburger menu & body
function toggleNav(elm, bodyElm){
$(elm).add(bodyElm).toggleClass('active')
.end()
.find('i').eq(0).toggleClass('fa-bars fa-times');
} // end func
Skills
Content Management
- ColdFusion
- Adobe Experience Manager (AEM)
- SEO/Web Analytics – Adobe
Technical Development
- HTML5
- CSS4
- Bootstrap
- jQuery
- JSON
- Angular
- PHP
- XML
- Git
- UI Design
- Responsive Web Design
Other Software
- Photoshop
- Microsoft Office Suite
- Dreamweaver
- Eclipse
- Visual Studio