Scaling Hamburger Navigation
Documentation
Webflow
Code
Step 1: Add HTML
HTML
Copy
<nav data-navigation-status="not-active" class="navigation">
<div data-navigation-toggle="close" class="navigation__dark-bg"></div>
<div class="hamburger-nav">
<div class="hamburger-nav__bg"></div>
<div class="hamburger-nav__group">
<p class="hamburger-nav__menu-p">Menu</p>
<ul class="hamburger-nav__ul">
<div class="hamburger-nav__li">
<a href="index.html" aria-current="page" class="hamburger-nav__a">
<p class="hamburger-nav__p">Home</p>
<div class="hamburger-nav__dot"></div>
</a>
</div>
<div class="hamburger-nav__li">
<a href="#" class="hamburger-nav__a">
<p class="hamburger-nav__p">Portfolio</p>
<div class="hamburger-nav__dot"></div>
</a>
</div>
<div class="hamburger-nav__li">
<a href="#" class="hamburger-nav__a">
<p class="hamburger-nav__p">Our Expertises</p>
<div class="hamburger-nav__dot"></div>
</a>
</div>
<div class="hamburger-nav__li">
<a href="#" class="hamburger-nav__a">
<p class="hamburger-nav__p">Services</p>
<div class="hamburger-nav__dot"></div>
</a>
</div>
<div class="hamburger-nav__li">
<a href="#" class="hamburger-nav__a">
<p class="hamburger-nav__p">About</p>
<div class="hamburger-nav__dot"></div>
</a>
</div>
<div class="hamburger-nav__li">
<a href="#" class="hamburger-nav__a">
<p class="hamburger-nav__p">Contact</p>
<div class="hamburger-nav__dot"></div>
</a>
</div>
</ul>
</div>
<div data-navigation-toggle="toggle" class="hamburger-nav__toggle">
<div class="hamburger-nav__toggle-bar"></div>
<div class="hamburger-nav__toggle-bar"></div>
</div>
</div>
</nav>Step 2: Add CSS
CSS
Copy
.navigation {
z-index: 500;
pointer-events: none;
position: fixed;
inset: 0;
}
.navigation__dark-bg {
transition: all 0.7s cubic-bezier(0.5, 0.5, 0, 1);
opacity: 0;
pointer-events: auto;
visibility: hidden;
background-color: #000;
position: absolute;
inset: 0;
}
[data-navigation-status="active"] .navigation__dark-bg {
opacity: 0.33;
visibility: visible;
}
.hamburger-nav {
border-radius: 1.5em;
position: absolute;
top: 2em;
right: 2em;
}
.hamburger-nav__bg {
transition: all 0.7s cubic-bezier(0.5, 0.5, 0, 1);
background-color: #e2e1df;
border-radius: 1.75em;
width: 3.5em;
height: 3.5em;
position: absolute;
top: 0;
right: 0;
}
[data-navigation-status="active"] .hamburger-nav__bg {
width: 100%;
height: 100%;
}
.hamburger-nav__group {
transition: all 0.5s cubic-bezier(0.5, 0.5, 0, 1), transform 0.7s cubic-bezier(0.5, 0.5, 0, 1);
grid-column-gap: 1em;
grid-row-gap: 1em;
pointer-events: auto;
transform-origin: 100% 0;
flex-flow: column;
padding: 2.25em 2.5em 2em 2em;
display: flex;
position: relative;
transform: scale(0.15) rotate(0.001deg);
opacity: 0;
visibility: hidden;
}
[data-navigation-status="active"] .hamburger-nav__group {
transform: scale(1) rotate(0.001deg);
opacity: 1;
visibility: visible;
}
.hamburger-nav__menu-p {
opacity: .5;
letter-spacing: .1em;
text-transform: uppercase;
margin-bottom: 0;
font-family: RM Mono, Arial, sans-serif;
font-size: 1em;
font-weight: 400;
}
.hamburger-nav__ul {
grid-column-gap: .375em;
grid-row-gap: .375em;
flex-flow: column;
margin-top: 0;
margin-bottom: 0;
padding: 0;
display: flex;
position: relative;
}
.hamburger-nav__li {
margin: 0;
padding: 0;
list-style: none;
}
.hamburger-nav__a {
color: #131313;
justify-content: space-between;
align-items: center;
text-decoration: none;
display: flex;
}
.hamburger-nav__a[aria-current] .hamburger-nav__p {
opacity: 0.33;
}
.hamburger-nav__p {
white-space: nowrap;
margin-bottom: 0;
padding-right: 1.25em;
font-size: 2em;
}
.hamburger-nav__dot {
transition: all 0.7s cubic-bezier(0.5, 0.5, 0, 1);
background-color: currentColor;
border-radius: 50%;
flex-shrink: 0;
width: .5em;
height: .5em;
transform: scale(0) rotate(0.001deg);
opacity: 0.5;
}
.hamburger-nav__a[aria-current] .hamburger-nav__dot {
transform: scale(1) rotate(0.001deg);
opacity: 1;
}
.hamburger-nav:has(.hamburger-nav__a:hover) .hamburger-nav__dot {
transform: scale(0) rotate(0.001deg);
}
.hamburger-nav .hamburger-nav__a:hover .hamburger-nav__dot {
transform: scale(1) rotate(0.001deg);
opacity: 0.25;
}
.hamburger-nav__toggle {
transition: transform 0.7s cubic-bezier(0.5, 0.5, 0, 1);
pointer-events: auto;
cursor: pointer;
border-radius: 50%;
justify-content: center;
align-items: center;
width: 3.5em;
height: 3.5em;
display: flex;
position: absolute;
top: 0;
right: 0;
transform: translate(0em, 0em) rotate(0.001deg);
}
[data-navigation-status="active"] .hamburger-nav__toggle {
transform: translate(-1em, 1em) rotate(0.001deg);
}
.hamburger-nav__toggle-bar {
transition: transform 0.7s cubic-bezier(0.5, 0.5, 0, 1);
background-color: #131313;
width: 40%;
height: .125em;
position: absolute;
transform: translateY(-0.15em) rotate(0.001deg);
}
.hamburger-nav__toggle:hover .hamburger-nav__toggle-bar {
transform: translateY(0.15em) rotate(0.001deg);
}
[data-navigation-status="active"] .hamburger-nav__toggle .hamburger-nav__toggle-bar {
transform: translateY(0em) rotate(45deg);
}
.hamburger-nav__toggle .hamburger-nav__toggle-bar:nth-child(2) {
transition: transform 0.7s cubic-bezier(0.5, 0.5, 0, 1);
transform: translateY(0.15em) rotate(0.001deg);
}
.hamburger-nav__toggle:hover .hamburger-nav__toggle-bar:nth-child(2) {
transform: translateY(-0.15em) rotate(0.001deg);
}
[data-navigation-status="active"] .hamburger-nav__toggle .hamburger-nav__toggle-bar:nth-child(2) {
transform: translateY(0em) rotate(-45deg);
}Step 2: Add Javascript
Step 3: Add Javascript
Javascript
Copy
function initScalingHamburgerNavigation() {
// Toggle Navigation
document.querySelectorAll('[data-navigation-toggle="toggle"]').forEach(toggleBtn => {
toggleBtn.addEventListener('click', () => {
const navStatusEl = document.querySelector('[data-navigation-status]');
if (!navStatusEl) return;
if (navStatusEl.getAttribute('data-navigation-status') === 'not-active') {
navStatusEl.setAttribute('data-navigation-status', 'active');
// If you use Lenis you can 'stop' Lenis here: Example Lenis.stop();
} else {
navStatusEl.setAttribute('data-navigation-status', 'not-active');
// If you use Lenis you can 'start' Lenis here: Example Lenis.start();
}
});
});
// Close Navigation
document.querySelectorAll('[data-navigation-toggle="close"]').forEach(closeBtn => {
closeBtn.addEventListener('click', () => {
const navStatusEl = document.querySelector('[data-navigation-status]');
if (!navStatusEl) return;
navStatusEl.setAttribute('data-navigation-status', 'not-active');
// If you use Lenis you can 'start' Lenis here: Example Lenis.start();
});
});
// Key ESC - Close Navigation
document.addEventListener('keydown', e => {
if (e.keyCode === 27) {
const navStatusEl = document.querySelector('[data-navigation-status]');
if (!navStatusEl) return;
if (navStatusEl.getAttribute('data-navigation-status') === 'active') {
navStatusEl.setAttribute('data-navigation-status', 'not-active');
// If you use Lenis you can 'start' Lenis here: Example Lenis.start();
}
}
});
}
// Initialize Scaling Hamburger Navigation
document.addEventListener('DOMContentLoaded', function() {
initScalingHamburgerNavigation();
});Implementation
Navigation Status
In this resource, we apply the [data-navigation-status="not-active"] attribute to the <nav> element. However, you can also place it on the <body> if you want to target all child elements on the page.
Open/Close Navigation
- Use
[data-navigation-toggle="toggle"]attribute to toggle the status active/not-active - Use
[data-navigation-toggle="close"]attribute to set the status not-active
Resource details
Published
March 17, 2025
Category
Navigation
Popularity
3.4K visitors
Need help?
Join Slack