Animated active menuitem background
Animated active menuitem background
by Csaba Hellinger
HTML
<div class="nav-bg">
<nav>
<!-- add an "underline" class after "animation" -->
<div class="animation"></div>
<a href="#" class="active">Home</a>
<a href="#">About</a>
<a href="#">Blog</a>
<a href="#">Portfolio</a>
<a href="#">Contact</a>
</nav>
</div>
CSS
@import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');
body {
font-family: 'Open Sans', sans-serif;
background: #2c3e50;
margin: 0;
padding: 0;
}
.nav-bg {
background: linear-gradient(0deg, transparent, #0008);
}
nav {
margin: 0 auto;
width: max-content;
position: relative;
}
nav a {
position: relative;
font-size: 15px;
text-transform: uppercase;
color: white;
text-decoration: none;
line-height: 100%;
display: inline-block;
text-align: center;
padding: 2rem 1rem;
text-shadow: 1px 1px 3px black;
opacity: 0.7;
transition: opacity 200ms;
}
nav a.active {
opacity: 1;
}
nav .animation {
position: absolute;
top: 0;
bottom: 0;
width: 0;
background: #1a8dbc;
pointer-events: none;
transition: all 200ms cubic-bezier(0, 0, 0.85, 0.12);
}
/* only underline */
nav .animation.underline {
top: unset;
height: 0.1rem;
bottom: 1.4rem;
}
JavaScript
const nav = document.querySelector('nav');
const animation = document.querySelector('nav .animation');
nav.onclick = ({ target }) => {
const { tagName, offsetLeft, offsetWidth } = target;
if (tagName === 'A') {
animation.style.left = `${offsetLeft}px`;
animation.style.width = `${offsetWidth}px`;
// simulate active class
nav.querySelector('a.active').classList.remove('active');
target.classList.add('active');
}
};