Skip to main content
Inspiring
December 9, 2022
Question

CSS dropdown menu in mobile view, collapses too slow

  • December 9, 2022
  • 2 replies
  • 835 views

I coded a navigation bar. It works mostly alright, but the sub-menu collapses too slow in mobile view. It looks garbled up for a few seconds and then disappears. I'm not sure what to do. I've tried to disable animation effects in the media query, but I've had no luck. The li:hover code in the media query is the issue, specifically:

 

.nav-menu li:hover> .sub-menu{
opacity: 1;
visibility: visible;
max-height: initial;
}
 
Here is the rest of the code:
/* Add a black background color to the top navigation */
*{padding: 0;
margin: 0;
box-sizing: border-box;
}
 
 header {background-color: #262626;}
 li {list-style: none;}
 a{color:white;
text-decoration: none;}
 
.navbar {
min-height: 70px;
display:flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
 
}
.menu-icons{color: blue;
font-size: 4rem;
position: absolute;
top: 50%;
right: 2rem;
transform: translateY(-50%);
cursor: pointer;
z-index: 1500;
display: none;
}
 
.nav-menu {
display:flex;
justify-content: space-between;
align-items: center;
gap: 60px;
}
 
 
.nav-menu li:hover>.sub-menu{
top: 4rem;
opacity: 1;
visibility: visible;}
 
.sub-menu li:hover>.sub-menu{
top: 0rem;
left: 8rem;
}
.nav-branding {
font-size: 2rem;
}
.nav-link{
transition: 0.7s ease;
font-size: 1.2rem;
}
 
.nav-link:hover{
color: dodgerblue;
}
 
.nav-link-2{
transition: 0.7s ease;
font-size: 2rem;
}
 
.nav-link-2:hover{
color: dodgerblue;
}
 
.hamburger {display: none;
cursor: pointer}
 
.bar{display:block;
width: 25px;
height: 3px;
margin: 5px auto;
transition: 0.3s;
transition-timing-function: ease-in-out; 
background: white;
 
}
.sub-menu {
line-height: 2rem;
width: max-content;
padding-left: 5px;
padding-right: 5px;
display: block;
position: absolute;
border-top: 3px solid #145DDD;
background-color: #191919;
z-index: 100;
transition: all 650ms ease;
top: 4rem;
visibility: hidden;
border-radius: 0;
 
}
.sub-menu::before {
content: "";
position: absolute;
top: -1.5rem;
left: 2rem;
border: 0.6rem solid transparent;
border-bottom-color: cornflowerblue;
 
}
.sub-menu .sub-menu::before {
top: 0rem;
left: -1.5rem;
border: 0.6rem solid transparent;
border-right-color: cornflowerblue;
}
 
.sub-menu .sub-menu {
top: 0;
border-top:none;
border-left: 3px solid cornflowerblue;
left: 160%;
}
 
.nav-menu li:hover > .sub-menu {
top: 4rem;
opacity: 1;
visibility: visible;
}
 
.sub-menu li:hover > .sub-menu {
 
top: inherit;
left: 110%;
margin-top: -1.5rem;
border-radius: 0;
}
 
@media(max-width:786px){
.hamburger{display: block;}
.hamburger.active .bar:nth-child(2){
opacity: 0;
}
.hamburger.active .bar:nth-child(1){
transform: translateY(8px) rotate(45deg);
}
.hamburger.active .bar:nth-child(3){
transform: translateY(-8px) rotate(-45deg);}
 
.nav-menu{
position: fixed;
left: -100%;
top: 70px;
gap: 0;
flex-direction: column;
background-color: #262626;
width: 100%;
text-align: center;
}
 
.nav-link{
font-size: 1.2rem;
}
 
.nav-item {
margin: 16px 0;
.nav-menu.active{
left: 0;
}
.sub-menu {
position: initial;
border: 3px solid transparent;
border-left-color: cornflowerblue;
margin-left: 1rem;
max-height: 0;
}
.sub-menu::before {
display: none;
}
.nav-menu li:hover> .sub-menu{
opacity: 1;
visibility: visible;
max-height: initial;
}
 
.sub-menu .sub-menu {display: none;}
}
 
 
 
    This topic has been closed for replies.

    2 replies

    Nancy OShea
    Community Expert
    Community Expert
    December 9, 2022

    By way of comparison, MDB has examples of Bootstrap multi-level dropdowns.

    https://mdbootstrap.com/docs/standard/extended/dropdown-multilevel/#

     

    MDB basics are free.  MDB premium components require a license.

    https://mdbootstrap.com/general/license/

     

    Nancy O'Shea— Product User & Community Expert
    Inspiring
    December 10, 2022

    I did get my navbar to work after some modifications. I was also able to get rid of the residual pixels that occures in mac os safari. The mobile version does have one generation dropdown but the second generation only works in desktop view. I thought that would be fine and I didn't want to obsess over it. It is my first navbar with no frameworks. A good learning experience. 

    Nancy OShea
    Community Expert
    Community Expert
    December 9, 2022

    If animation is managed with CSS alone and not JavaScript, adjust your CSS transition speed in seconds.

    https://www.w3schools.com/css/css3_transitions.asp

     

    Nancy O'Shea— Product User & Community Expert
    Inspiring
    December 9, 2022

    Thanks, I have been experimenting with transition properties. No luck so far. There is also javascript....

    const hamburger = document.querySelector(".hamburger");
    const navMenu = document.querySelector(".nav-menu");
     
    hamburger.addEventListener("click", () => {
     
    hamburger.classList.toggle("active");
    navMenu.classList.toggle("active");
    })
     
    document.querySelectorAll(".nav-link").forEach(n=> n.addEventListener("click", ()=>{
    hamburger.classList.remove("active");
    navMenu.classList.remove("active");
    }))
     
    document.addEventListener("DOMContentLoaded", function(){
    // make it as accordion for smaller screens
    if (window.innerWidth < 992) {
     
      // close all inner dropdowns when parent is closed
      document.querySelectorAll('.navbar .dropdown').forEach(function(everydropdown){
        everydropdown.addEventListener('hidden.bs.dropdown', function () {
          // after dropdown is hidden, then find all submenus
            this.querySelectorAll('.submenu').forEach(function(everysubmenu){
              // hide every submenu as well
              everysubmenu.style.display = 'none';
            });
        })
      });
     
      document.querySelectorAll('.dropdown-menu a').forEach(function(element){
        element.addEventListener('click', function (e) {
            let nextEl = this.nextElementSibling;
            if(nextEl && nextEl.classList.contains('submenu')) {
              // prevent opening link if link needs to open dropdown
              e.preventDefault();
              if(nextEl.style.display == 'block'){
                nextEl.style.display = 'none';
              } else {
                nextEl.style.display = 'block';
              }
     
            }
        });
      })
    }
    // end if innerWidth
    }); 
    // DOMContentLoaded  end
    Nancy OShea
    Community Expert
    Community Expert
    December 9, 2022

    The trouble with code you find on the Internet is that you get what you pay for, warts & all.

     

    I don't see anything in your JS that would effect transition speed.  Also it could be that your mobile device just isn't as fast as your desktop. 

     

    Nancy O'Shea— Product User & Community Expert