Search code examples
csskeyboardaccessibilityfocusmegamenu

Make Mega menu visible on focus, not just hover


I'm trying to make a mega menu visible on focus, not just hover. Not sure what I'm doing wrong - it's at https://deltadentalcofoundation.org/ Here's the HTML:

<ul id="menu-main-2022" class="nav-menu dl-menu submenu-icon styled">
    <li id="menu-item-31816" class="menu-item menu-item-type-post_type menu-item-object-page current-page-ancestor current-menu-ancestor current-menu-parent current-page-parent current_page_parent current_page_ancestor menu-item-has-children menu-item-parent menu-item-31816 megamenu-template-enable megamenu-first-element mobile-clickable menu-item-current" data-template="32343">
        <a href="https://deltadentalcofoundation.org/about-us/">About Us<i class="default"></i></a><span class="menu-item-parent-toggle"></span>
        <div class="megamenu-template template-width-fullwidth template-framing-border megamenu-template-item-inited megamenu-template-inited"> 

The CSS to make div.megamenu-template visible on hover is as follows:

.thegem-te-menu__default.desktop-view ul.nav-menu > li:hover > .megamenu-template {
    visibility: visible;
    opacity: 1;
    transition: transform 0.3s linear, opacity 0.3s linear, visibility 0.3s linear;
    transform: translateY(0);
}

From what I understand, I can't focus on the li, so I've been trying to focus on the a nested inside the li, and then using the adjacent selector to make the div.megamenu-template visible. I've tried all the below, but can't make it work... any ideas?

.thegem-te-menu__default.desktop-view ul.nav-menu > li > a:focus + .megamenu-template,
.thegem-te-menu__default.desktop-view ul.nav-menu > li > a:focus-visible + .megamenu-template,
.thegem-te-menu__default.desktop-view ul.nav-menu > li > a:focus-within + .megamenu-template,
.thegem-te-menu__default.desktop-view ul.nav-menu > li:focus-within > .megamenu-template,
.thegem-te-menu__default.desktop-view ul.nav-menu > li:hover > .megamenu-template,
.thegem-te-menu__default.desktop-view ul.nav-menu > li:focus-within > .megamenu-template,
.thegem-te-menu__default.desktop-view ul.nav-menu > li > .megamenu-template:hover,
.thegem-te-menu__default.desktop-view ul.nav-menu > li:focus-visible > .megamenu-template,
.thegem-te-menu__default.desktop-view ul.nav-menu > li:focus-within > .megamenu-template,
.thegem-te-menu__default.desktop-view ul.nav-menu > li > .megamenu-template:focus-visible,
ul.nav-menu > li:focus-visible > .megamenu-template,
ul.nav-menu > li:focus-within > .megamenu-template,
ul.nav-menu > li > .megamenu-template:focus-visible,
.thegem-te-menu__default.desktop-view ul.nav-menu > a:focus > .megamenu-template,
.thegem-te-menu__default.desktop-view ul.nav-menu > a:focus-visible > .megamenu-template {
    visibility: visible !important;
    opacity: 1 !important;
    transition: transform 0.3s linear, opacity 0.3s linear, visibility 0.3s linear !important;
    transform: translateY(0) !important;
}

Solution

  • Yes, you cannot focus the <li> itself, and the mega menu needs to stay open once focus moves away from the triggering, parent item to its child items.

    Therefore, your only choice is :focus-within.

    .megamenu-template {
      visibility: hidden;
    }
    
    .menu-item:focus-within .megamenu-template {
      visibility: visible;
    }
    <ul class="nav-menu dl-menu">
        <li class="menu-item">
            <a href="#">About Us <i aria-hidden="true" class="default"></i></a><span class="menu-item-parent-toggle"></span>
            <div class="megamenu-template">
            MEGA MENU
            <a href="#">Submenu item</a>
            </div>
        </li>
        <li class="menu-item">
          <a href="#">Menu item</a>
        </li>
    </ul>

    If in your example this didn’t work, it might be due to other selectors or missing classes elsewhere.

    Use your browser developer tools to investigate.


    Don’t forget to either hide your icons from assistive technology with aria-hidden or providing an alternative text.

    Also, the current page should be marked in the link with aria-current="page".

    See also the [ Example Disclosure Navigation Menu on the ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/example-index/disclosure/disclosure-navigation.html

    They don’t open submenus on focus, but via toggles.