A navigation that sticks on the bottom of the viewport and enables a quick navigation on mobile devices.
A Pen by Matthew Daniel Brown on CodePen.
<div class="quickNav"> | |
<!-- Menus --> | |
<div class="quickNav__menus"> | |
<div id="one" class="quickNav__menu"> | |
<a href="#" class="quickNav__link">Menu Item One</a> | |
<a href="#" class="quickNav__link">Menu Item Two</a> | |
<a href="#" class="quickNav__link">Menu Item Three</a> | |
<a href="#" class="quickNav__link">Menu Item Fourth</a> | |
</div> | |
<div id="two" class="quickNav__menu"> | |
<a href="#" class="quickNav__link">Menu Item One</a> | |
<a href="#" class="quickNav__link">Menu Item Two</a> | |
</div> | |
<div id="three" class="quickNav__menu"> | |
<a href="#" class="quickNav__link">Menu Item One</a> | |
<a href="#" class="quickNav__link">Menu Item Two</a> | |
<a href="#" class="quickNav__link">Menu Item Three</a> | |
<a href="#" class="quickNav__link">Menu Item Fifth</a> | |
<a href="#" class="quickNav__link">Menu Item Sixth</a> | |
</div> | |
<div id="fourth" class="quickNav__menu"> | |
<a href="#" class="quickNav__link">Menu Item One</a> | |
<a href="#" class="quickNav__link">Menu Item Two</a> | |
</div> | |
</div> | |
<!-- Items --> | |
<div class="quickNav__items"> | |
<a href="#one" class="quickNav__item"> | |
<span class="quickNav__icon"></span> | |
<span class="quickNav__label">Item One</span> | |
</a> | |
<a href="#two" class="quickNav__item"> | |
<span class="quickNav__icon"></span> | |
<span class="quickNav__label">Item Two</span> | |
</a> | |
<a href="#three" class="quickNav__item"> | |
<span class="quickNav__icon"></span> | |
<span class="quickNav__label">Item Three</span> | |
</a> | |
<a href="#fourth" class="quickNav__item"> | |
<span class="quickNav__icon"></span> | |
<span class="quickNav__label">Item Fourth</span> | |
</a> | |
</div> | |
</div> |
const quickNav = document.querySelector('.quickNav') | |
const items = quickNav.querySelectorAll('.quickNav__item') | |
const closeAll = function() { | |
const activeMenus = quickNav.querySelectorAll('.quickNav__menu.active') | |
const activeItems = quickNav.querySelectorAll('.quickNav__item.active') | |
quickNav.classList.remove('active') | |
Array.prototype.forEach.call(activeItems, (activeItem) => activeItem.classList.remove('active')) | |
Array.prototype.forEach.call(activeMenus, (activeMenu) => activeMenu.classList.remove('active')) | |
} | |
quickNav.onclick = closeAll | |
Array.prototype.forEach.call(items, function(item) { | |
item.onclick = (e) => { | |
e.stopPropagation() | |
e.preventDefault() | |
const href = item.getAttribute('href') | |
const newMenu = quickNav.querySelector(href) | |
const isActive = newMenu.classList.contains('active') | |
closeAll() | |
if (isActive===false) { | |
quickNav.classList.add('active') | |
newMenu.classList.add('active') | |
item.classList.add('active') | |
} | |
} | |
}) |
.quickNav { | |
position: fixed; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
&::before { | |
content: ''; | |
position: absolute; | |
height: 100vh; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
background: rgba(0, 0, 0, .4); | |
opacity: 0; | |
transition: opacity .4s ease; | |
will-change: opacity; | |
} | |
&.active::before { | |
opacity: 1; | |
} | |
&__items { | |
position: relative; | |
display: flex; | |
align-items: center; | |
justify-content: space-around; | |
background: white; | |
box-shadow: 0 -1px 3px rgba(0, 0, 0, .05); | |
z-index: 1; | |
} | |
&__item { | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
padding: .5em 0; | |
text-decoration: none; | |
} | |
&__icon { | |
margin: 0 0 .25em; | |
width: 2em; | |
height: 2em; | |
background: black; | |
border-radius: 100%; | |
opacity: .4; | |
transition: opacity .4s ease; | |
will-change: opacity; | |
} | |
&__item.active &__icon { | |
opacity: 1; | |
} | |
&__label { | |
color: #222; | |
font-size: .8em; | |
transition: color .4s ease; | |
} | |
&__item.active &__label { | |
background: #00; | |
} | |
&__menu { | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
background: white; | |
box-shadow: 0 -2px 3px rgba(0, 0, 0, .05); | |
transform: translateY(10%); | |
transition: transform .4s ease; | |
will-change: transform; | |
&.active { | |
transform: translateY(-100%); | |
} | |
} | |
&__link { | |
display: block; | |
padding: 1em; | |
color: #222; | |
text-decoration: none; | |
border-bottom: 1px solid rgba(0, 0, 0, .05); | |
} | |
} | |
body { | |
background: #eee; | |
} |