You are currently viewing Animated Modern Menu with Elementor & GSAP #4

Animated Modern Menu with Elementor & GSAP #4

(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 – Floating Animated Modern Menu with Elementor & GSAP

In this tutorial, we are creating a floating bar that collapses and extends when clicked on hamburger icon. We also have a submenu box that automatically follows the menu links when hovered. The submenu links are switches to appropriate ones while the background box follows the hovered menu link.

Reminder: The floating bar is not responsive for mobile/tablet devices due to its nature. So make sure to hide it for mobile/tablet devices via the responsive settings available in Elementor page builder.

Floating Bar Animated Menu – Elementor and GSAP

  1. dm-menu-container-4 is the CSS class of the Menu container that contains the logo, links and hamburger menu.
  2. min(98%, 800px); is the width given to the menu container that contains all.
  3. dm-menu-list-container-4 is the CSS class of the container that contains the page links. (The middle container between logo and hamburger icon).
  4. dm-menu-icon-4 is the CSS class of the hamburger menu icon that opens/closes the menu bar.
  5. To change the width of the middle container ( page links container), change the CSS code in dm-menu-list-container-4. Change both width & max-width to your desired value.
  6. For the collapsed menu bar size, change the width:150 to your desired final width size. 
  7. dm-submenu-list is the extra CSS class given to menu page links that should show submenus. The CSS class of the submenu page link should look like “dm-menu-list-4 dm-submenu-list“. 
				
					<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>

<style>
    
    .dm-menu-container-4 {
    
        position: fixed;
        bottom: 20px;
        left: 50%;
        transform: translate(-50%, 0%);
        z-index: 9999;
    }
   
   .dm-menu-list-container-4 {
       
       width:60%;
       max-width:60%;
       
   }
   
    
</style>


<script>
    
    const dmMenuIcon4 = document.querySelector('.dm-menu-icon-4');
    const dmMenuContainer4 = document.querySelector('.dm-menu-container-4');
    
    const dmMenu4 = gsap.timeline();    
    
    dmMenu4.pause();
    
    let dmMenu4Open = false;

    
    dmMenu4.to('.dm-menu-list-4', {
        
       opacity:0,
       duration:0.2,
       stagger:-0.1
        
        
    });
    
     dmMenu4.to('.dm-menu-list-4', {
        
       scale:0,
       height:0,
       duration:0
        
    });
    
    dmMenu4.to('.dm-menu-list-container-4', {
        
       maxWidth:'0%',
       padding:0,
       gap:0,
       duration:1
        
    });
    
    dmMenu4.to('.dm-menu-container-4', {
	
	   width:150,
	   duration:1


   },'-=1');
   
   
    
    dmMenuIcon4.addEventListener('click', () => {
        
        if(dmMenu4Open == false) {
            dmMenu4.timeScale(1).play();
            dmMenuIcon4.classList.add('active');
        }
        else {
            dmMenu4.timeScale(1).reverse();
            dmMenuIcon4.classList.remove('active');
        }
        
        dmMenu4Open = !dmMenu4Open;
        
    });

</script>
				
			

Add Submenu to the floating bar – Elementor & GSAP

  1. dm-submenu-4 is the CSS class of the main container that contains all submenu child container.
  2. dm-submenu-list is the extra CSS class given to menu page links that should show submenus. The CSS class of the submenu page link should look like “dm-menu-list-4 dm-submenu-list“. 
  3. dm-submenu-4-content is the CSS class of containers that have submenu page links/contents. (These are given to child containers of the parent container dm-submenu-4)
  4. The order of submenu content containers and menu page links should be same. Else the submenu will not show in the right page link.
				
					<style>
    .dm-submenu-4 {
        transition: height 0.3s, left 0.3s, opacity 0.3s !important;
        opacity: 1;
        z-index: 9999;
        height: 0;
        overflow: hidden;
    }
    
    .dm-submenu-4-content {
        transition: opacity 1s; /*This will not change transition, transition duration is controlled by javascript*/
        opacity: 0; /* Start with opacity 0 */
        
    }
</style>

<script>
   const dmSubmenuLists = document.querySelectorAll('.dm-submenu-list');
const dmSubmenu4 = document.querySelector('.dm-submenu-4');
const dmSubmenu4Content = document.querySelectorAll('.dm-submenu-4-content');
const dmSubmenuHeightList = [];
let submenuVisible = false; // Flag to check if submenu should be visible

dmSubmenu4Content.forEach((dmSubmenuHeight) => {
    dmSubmenuHeightList.push(dmSubmenuHeight.offsetHeight);
    dmSubmenuHeight.style.display = 'none';
});

dmSubmenu4.addEventListener('mouseover', () => {
    submenuVisible = true;
    dmSubmenu4.style.opacity = 1;
});

dmSubmenu4.addEventListener('mouseleave', () => {
    submenuVisible = false;
    hideSubmenuWithDelay();
});

console.log(`Height Array : ${dmSubmenuHeightList}`);

dmSubmenuLists.forEach((dmSubmenuList, index) => {
    dmSubmenuList.addEventListener('mouseenter', () => {
        submenuVisible = true;
        const dmSubmenuBox = dmSubmenuList.getBoundingClientRect();
        const dmSubMenuListWidth = dmSubmenuList.offsetWidth;
        dmSubmenu4.style.left = dmSubmenuBox.left + (dmSubMenuListWidth / 2) + 'px';
        dmSubmenu4.style.transform = 'translate(-50%, 0%)';
        dmSubmenu4.style.height = dmSubmenuHeightList[index] + 'px';
        dmSubmenu4.style.opacity = 1;
    });

    dmSubmenuList.addEventListener('mouseover', () => {
        dmSubmenu4Content.forEach((content, contentIndex) => {
            content.style.opacity = 0;
            content.style.transition = 'opacity 0.3s';
            setTimeout(() => {
                content.style.display = 'none';
            }, 300); // Match the transition duration

            if (contentIndex === index) {
                setTimeout(() => {
                    content.style.display = 'flex';
                }, 310);

                setTimeout(() => {
                    content.style.transition = 'opacity 0.3s';
                    content.style.opacity = 1;
                }, 320);
            }
        });
    });

    dmSubmenuList.addEventListener('mouseleave', () => {
        submenuVisible = false;
        hideSubmenuWithDelay();
    });
});

function hideSubmenuWithDelay() {
    setTimeout(() => {
        if (!submenuVisible) {
            dmSubmenu4.style.opacity = '0';
            dmSubmenu4.style.height = '0';
            dmSubmenu4Content.forEach(content => {
                content.style.opacity = 0;
                content.style.transition = 'opacity 0.3s';
                setTimeout(() => {
                    content.style.display = 'none';
                }, 300);
            });
        }
    }, 300); // Adjust delay as needed
}

    
</script>

				
			

Leave a Reply