I have a button to toggle opening and closing of a dropdown menu with CSS transition. Suppose I have this HTML for a dropdown menu and a toggle button:
<button type="button" id="main-nav-collapse-button" aria-label="Click to expand or collapse the main navigation menu" >☰</button>
...
<nav role="navigation" id="main-nav"><ul>
<li>...</li>
<li>...</li>
<li>...</li>
</ul></nav>
Instead of opening/closing the nav dropdown with JS, I have minimal JS to just add/remove a class .expanded to/from the <ul>.
I have transition in the CSS so that the opening/closing is animated:
#main-nav>ul {
display:none;
max-height:0;
overflow:hidden;
transition: height 0.5s linear;
}
#main-nav>ul.expanded {
display:block;
max-height: 100vh;
}
The problem with the above code is that the opening/closing do not transition/animate because I have display CSS property specified in both states. display cannot be transition/animated and it is toggled straight away when the class is added/removed.
In contrast, if I remove the display properties in the CSS, it does animate. The only problem is that the menu is only hidden from users (height=0) but not preventing the menu from being accessed. When users use keyboard-navigation by tapping , the menu items in the menu are still focusable even they are visibly 'hidden'. I haven't found a solution to disable the focus with CSS.
I am hoping there is a way to apply the display property change before/after the CSS transition. I haven't got a pure CSS approach. My current fallback is to apply the change of display property before/after the class-toggle with a delay using JS, but I just feel that this approach is more like a patch to the problem rather than a proper solution.
It will be great if there is a non-JS solution.
Side note: I could have made the class-toggling part non-JS-dependent too, but unfortunately the button and the nav don't share the same parent in DOM. Making the dropdown to appear/hide on hover without JS would be extremely difficult.