(This page includes affiliate links. If you click and purchase, I receive a small commission at no extra cost from you and that way you can support me. I only recommend tools that I have personally used and loved.)
Get Elementor Pro Today –
1 – Elementor Pro
Don’t want to make from scratch? Buy the template instead 🙂
Introduction – Animated Modern Menu #13 with Elementor & GSAP
In this tutorial, we are learning to make GSAP animated menu that opens/closes when clicked on our toggle button. This menu is fully responsive and creates amazing staggering column-like effect when opening and closing.
Animated Hamburger Icon (Toggle between Open and Close Icon)
- Refer to this video to understand it better. (https://youtu.be/FzcW342IJ-c?t=202)
- Width in .menu-icon changes width of the hamburger icon.
- height in .menu-icon changes the distance between each line.
- height in .line changes the thickness of the each lines.
- .menu-wrapper contains the styling for background, padding, border etc.
- Each CSS class has an .active state, change the appropriate values for background, border etc.
<div class="menu-wrapper" id="menu-wrapper">
<div id="menu-icon" class="menu-icon">
<div class="line top"></div>
<div class="line middle"></div>
<div class="line bottom"></div>
</div>
</div>
<style>
:root {
--dm-normal-delay: 1s;
--dm-active-delay: 0s;
--dm-menu-transition: 0.3s;
}
.menu-icon {
width: 30px;
height: 25px;
position: relative;
cursor: pointer;
transition: transform var(--dm-menu-transition) ease;
transition-delay: var(--dm-normal-delay);
}
.line {
width: 100%;
height: 5px;
background-color: black;
position: absolute;
transition: all var(--dm-menu-transition) ease;
transition-delay: var(--dm-normal-delay);
}
.top {
top: 0;
transition-delay: var(--dm-normal-delay);
}
.middle {
top: 50%;
transform: translateY(-50%);
transition-delay: var(--dm-normal-delay);
}
.bottom {
bottom: 0;
transition-delay: var(--dm-normal-delay);
}
.menu-wrapper {
padding: 10px;
border: 2px solid black;
transition: all var(--dm-menu-transition) ease;
background: white;
transition-delay: var(--dm-normal-delay);
}
.menu-wrapper.active .menu-icon {
transform: rotate(360deg);
transition-delay: var(--dm-active-delay);
}
.menu-wrapper.active .top {
transform: rotate(45deg);
top: 50%;
transform: translateY(-50%) rotate(45deg);
background-color: white;
transition-delay: var(--dm-active-delay);
}
.menu-wrapper.active .middle {
opacity: 0;
transition-delay: var(--dm-active-delay);
}
.menu-wrapper.active .bottom {
transform: rotate(-45deg);
bottom: 50%;
transform: translateY(50%) rotate(-45deg);
background-color: white;
transition-delay: var(--dm-active-delay);
}
.menu-wrapper.active {
padding: 10px;
border: 2px solid white;
transition-delay: var(--dm-active-delay);
background: black;
}
</style>
<script>
document.getElementById('menu-wrapper').addEventListener('click', function() {
this.classList.toggle('active');
});
</script>
Animated Modern Menu #13
- dm-menu-anim-bg is the CSS class of the main container of the menu.
- dm-menu-anim-column is the CSS class of the inner column containers.
- dm-menu-social-anim is the CSS class of the social icons inside column container.
- dm-menu-title-anim is the CSS class of the menu titles. (Make sure to give it HTML tag p)
- dm-menu-anim-toggle is the CSS class of hamburger icon.
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js" integrity="sha512-7eHRwcbYkK4d9g/6tD/mhkf++eoTHwpNM9woBxtPUBWm67zeAfFC+HrdoE2GanKeocly/VxeLvIqwvCdk7qScg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js" integrity="sha512-onMTRKJBKz8M1TnqqDuGBlowlH0ohFzMXYRNebz+yOcc5TQr/zAKsthzhuv0hiyUKEiQEQXEynnXCvNTOk50dg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<style>
.dm-menu-anim-bg {
transition: none !important;
max-height: 100vh;
overflow-y: scroll;
display: none;
}
.dm-menu-anim-column, .dm-menu-social-anim {
transition: none !important;
}
.dm-menu-title-anim p{
transition: letter-spacing 0.3s;
overflow: hidden;
}
.dm-menu-title-anim p:hover {
letter-spacing: 5px !important;
}
/* Hides scrollbar in webkit browsers like chrome etc */
.dm-menu-anim-bg::-webkit-scrollbar {
width: 0px;
}
/* Hide scrollbar for firefox */
.dm-menu-anim-bg {
scrollbar-width: none;
}
</style>
<script>
const dmMenuIconAnim = document.querySelector('.dm-menu-anim-toggle');
const dmMenuAnimBG = document.querySelector('.dm-menu-anim-bg');
let dmMenuAnimActive = false;
const dmMenuAnimTimeline = gsap.timeline({
onStart: () => {
dmMenuAnimBG.style.display = 'flex';
},
onReverseComplete: () => {
dmMenuAnimBG.style.display = 'none';
}
});
dmMenuAnimTimeline.pause();
dmMenuIconAnim.addEventListener('click', () => {
if (dmMenuAnimActive) {
dmMenuAnimTimeline.reverse();
// body.classList.remove('no-scroll');
} else {
dmMenuAnimTimeline.play();
// body.classList.add('no-scroll');
}
dmMenuAnimActive = !dmMenuAnimActive;
});
// GSAP timeline
dmMenuAnimTimeline.from('.dm-menu-anim-column', {
y:'-100%',
duration:0.5,
stagger:-0.2,
ease:'power1.out'
});
dmMenuAnimTimeline.from('.dm-menu-title-anim', {
opacity:0,
duration:0.5,
stagger:0.1
}, '-=0.1')
dmMenuAnimTimeline.from('.dm-menu-social-anim', {
opacity:0,
duration:0.5
}, '-=0.3')
</script>