Search code examples
csshoverliferay-7megamenuliferay-7.3

CSS: Is there a way to not lose hover, if the mouse goes off for a split-second?


I'm creating a megamenu (opening with hover) and it'd be neat to not unhover, if the mouse goes over empty space for a split-second. The top bar buttons have a bit of space between them and moving mouse to the null-area will drop hover and hide the megamenu completely.

Megamenu-example The white square in the image is the button area. Both it and light-blue dropdown area display the dropdown with hover. However, leaving these areas for a split-second (arrow) causes the hover to be lost and the menu will hide.

How can I get the menu to refocus and not hide? I've tried using transition-delay, but haven't yet got it working, as the menu works with display: flex | none. I use display, as there are four separate dropdowns in the megamenu, but is there a better way I should use?

I'm using Liferay 7.3.2, if it makes any difference.


EDIT: Some of my code:

<ul id="megamenu-top">
    <li class="megamenu-top-item">
        <button class="megamenu-top-button">
            Top button
        </button>
        <ul class="megamenu-dropdown">
            <li class="megamenu-dropdown-item">
                <a href="/link">
                    Link
                </a>
            </li>
        </ul>
    </li>
</ul>

#megamenu-top {
    .megamenu-top-item {
        display: flex;
        width: 20%;
        height: 5rem;
        margin: auto;
        padding: 0 0.5rem;

        .megamenu-top-button {
            width: 100%;
            padding: 5px;
            border-width: 5px 0;
            margin: 1rem auto;
        }

        .megamenu-dropdown {
            display: none;
            width: 100%;
            position: absolute;
            padding: 5rem 5% 7rem;
            margin-top: 5rem;

            .megamenu-dropdown-item {
                width: 20%;
                margin: 1rem 6.66%;
                display: flex;

                a {
                    width: 100%;
                    display: flex;
                    justify-content: center;
                    padding: 1rem;
                }
            }
        }

        &:hover, &:focus-within, &:active {
            .megamenu-dropdown {
                display: flex;
            }
        }
    }
}


Solution

  • Like I said earlier: The easiest way is to add pseudoelement to the dropdown which will take the space between the button and the dropdown. So hover will not be lost when you'll move the mouse from the button to the dropdown. I've added background colors so you can see how it works, simply adjust sizes for your real offset

    #megamenu-top .megamenu-top-item {
      display: flex;
      width: 20%;
      height: 5rem;
      margin: auto;
      padding: 0 0.5rem;
    }
    #megamenu-top .megamenu-top-item .megamenu-top-button {
      width: 100%;
      padding: 5px;
      border-width: 5px 0;
      margin: 1rem auto;
    }
    #megamenu-top .megamenu-top-item .megamenu-dropdown {
      display: none;
      width: 100%;
      position: absolute;
      padding: 5rem 5% 7rem;
      margin-top: 5rem;
    }
    #megamenu-top .megamenu-top-item .megamenu-dropdown .megamenu-dropdown-item {
      width: 20%;
      margin: 1rem 6.66%;
      display: flex;
    }
    #megamenu-top .megamenu-top-item .megamenu-dropdown .megamenu-dropdown-item a {
      width: 100%;
      display: flex;
      justify-content: center;
      padding: 1rem;
    }
    #megamenu-top .megamenu-top-item:hover .megamenu-dropdown, #megamenu-top .megamenu-top-item:focus-within .megamenu-dropdown, #megamenu-top .megamenu-top-item:active .megamenu-dropdown {
      display: flex;
    }
    
    
    /* Added code */
    #megamenu-top .megamenu-top-item .megamenu-dropdown {
      background-color: #cecece;
    }
    
    /* For demo purposes */
    #megamenu-top .megamenu-top-item .megamenu-dropdown {
      margin-top: 7rem;
    }
    
    /* Pseudo for dropdown */
    #megamenu-top .megamenu-top-item .megamenu-dropdown::before {
      position: absolute;
      content: '';
      left: 0;
      bottom: 100%;
      height: 2rem;
      width: 100%;
      background-color: red;
    }
    <ul id="megamenu-top">
        <li class="megamenu-top-item">
            <button class="megamenu-top-button">
                Top button
            </button>
            <ul class="megamenu-dropdown">
                <li class="megamenu-dropdown-item">
                    <a href="/link">
                        Link
                    </a>
                </li>
            </ul>
        </li>
    </ul>