Solution 1 :

Very simple vanilla JS example using a timeout with a minor delay to determine whether or not to hide upon leaving.

let hideTimeout = false;

document.getElementById("hover-me").onmouseenter = function(event){
    document.getElementById("dropdown").style.display = "";
}

document.getElementById("hover-me").onmouseleave = function(event){
    hideTimeout = setTimeout(function(){
        document.getElementById("dropdown").style.display = "none";
    }, 10)
}

document.getElementById("dropdown").onmouseenter = function(event){
    if(hideTimeout !== false){
        clearTimeout(hideTimeout);
        hideTimeout = false;
    }
}

document.getElementById("dropdown").onmouseleave = function(event){
    document.getElementById("dropdown").style.display = "none";
}
#hover-me {
  width:40px;
  height:40px;
  background: blue;
}

#dropdown {
    position: absolute;
    top: 20px;
    left: 20px;
    width: 60px;
    height: 40px;
    background: #eee;
    box-shadow : 0 0 4px #555;
}
<div id="hover-me"></div>
<div id="dropdown" style="display:none;">
  Some content
</div>

Solution 2 :

I solved this by adding onopen and onclose handlers to the dropdown and the callbacks will add/remove a class on the container which is used to keep the menubar visible while the dropdown is open.

Problem :

I have a container div in which there is a dropdown control. Clicking the dropdown button opens up the dropdown menu. The initial problem I had was that if the container div has a very small height, the dropdown opens but results in a scrollbar. I figured out that it is not possible to have overflow-x: scroll and overflow-y: visible at the same time. This forced me to a new strategy for the dropdown. That is, to use @floating-ui (next version after Popper 2) that allows placing one element relative to the other. So, upon clicking the dropdown button, I move the dropdown menu from it’s immediate parent into the document’s body (so that the entire dropdown is always visible) and then attach the floating-ui. All of this works great. The only remaining problem is, the dropdown menus were initially displaying only when the user hovers over the container. But since the dropdown is moved into the document body, mouse over the dropdown doesn’t create the hover effect on the container anymore. Some of the answers suggest using pointer-event to none for the absolute div so that the pointer events propagate down. However, in my case, I want the user to use the mouse to click on any of the actions within the dropdown.

So, how do I achieve the effect I want which I am summarizing below:

  1. A container div which on :hover displays a navbar with dropdown buttons.
  2. Clicking any of the dropdown buttons will open the dropdown right below that button.
  3. The entire dropdown content should be visible even if the container height is smaller than the dropdown.
  4. While the mouse is on the dropdown menu, the navbar should continue to display.

enter image description here

Comments

Comment posted by Gerard

Adding the code of what you’ve tried and explaining where you run into problems says more than a 1000 words.

Comment posted by Rylee

Seems like you would be better handling this through JavaScript using events. When mouse enters the container, add a class

Comment posted by Siva

Thanks Rylee, I tried that but unfortunately, moving the mouse over to the dropdown area is triggering mouseleave on the container div even though physically the mouse hasn’t left. I think since the dropdown is attached to the body, regardless of where it is positioned, entering into it automatically triggers leave on other elements.

Comment posted by Rylee

There’s another approach you could take. Use

Comment posted by Siva

Thank you Rylee. I have added a small video of the issue. The setting is more complicated than what you have provided.

Comment posted by Rylee

@Siva I would apply the same logic that’s hiding the dropdown to also hide the menu. i.e. don’t hide the menu if the dropdown is open – if the dropdown is closed, hide the menu if the mouse didn’t re-enter

By