Skip to main content

Accessible Mega Menu

This page provides an example of a mega menu with hover support that has been optimized for accessibility. The code is available for resuse as a public GitHub archive with css/mega-menu-styles.css and js/mega-menu.js being the core files.

Design Specifications

Design Specifications Link

The Accessible Mega Menu was designed to meet the specific needs of a website redesign. A mega menu approach was desired as the site is a library and thus offers a variety of services that need to be discoverable by users without having to do deep diving. The current menu structure reflects a draft of the proposed site "structure."

The mega menu design request specified the following features:

HTML Structure

HTML Structure Link

The overall structure of the mega menu is a collection of basic disclosure patterns consisting of unordered lists and buttons.

Stacked Disclosure HTML
<h2 id="main-nav-heading" class="offscreen">
<nav class="mega-menu" aria-labelledby="main-nav-heading" data-menu-state="closed" data-responsive-width="900px">
  <button class="responsive-toggle" aria-expanded="false">
    <svg focusable="false" ><use xlink:href="#icon-menu"></use></svg>
    Menu
  </button>
  <ul>
    <li>
      <button aria-expanded="false" class="mega-menu-toggle">
        Services and Support
        <svg focusable="false" class="icon down"><use xlink:href="#icon-down-triangle"></use></svg>
        <svg focusable="false" class="icon up"><use xlink:href="#icon-up-triangle"></use></svg>
      </button>
      <div class="mega-sub-menu" tabindex="-1">
        <ul>
          <li class="image-column">
            <a href="">
              <img src="..." alt="..."/>
              <div>Image Link Heading</div>
            </a>
          </li>
          <li class="text-column">
             <div class="mega-sub-heading">Optional list heading</div>
             <ul class="mega-menu-bulleted">
               <li><a href="...">Link text<a></li>
               ...
             <ul>
          </li>
          <li class="text-column double">
             <div class="mega-sub-heading">Optional list heading</div>
             <ul class="mega-menu-bulleted">
               <li><a href="...">Link text<a></li>
               ...
             <ul>
          </li>
        </ul>
      </div><!-- End sub-menu -->
    </li>
    <li>
      <button aria-expanded="false" class="mega-menu-toggle">...</button>
      <div class="mega-sub-menu" tabindex="-1">...</div>
    </li>
	...
  </ul>
</nav>

Within a sub-menu, there are four equal-width columns (25%) available. Columns can involve an image or text. Text columns can also be marked as a double column in that the list of items will be displayed across two columns (50% of the width). CSS is used to prevent individual list items from breaking across the columns.

Accessibility Concerns

Accessibility Concerns Link

The mega menu is a collection of drop down menus for navigation. As such, each dropdown should thus mostly follow the recommended practices for the WAI-ARIA disclosure pattern. The example provided for navigation menu examples via disclosures can be used. In terms of accessibility features, the following subsections discuss what is needed for proper implementation.

Importantly, note that this is NOT an application menu and that pattern should not be used. Application menus are for web applications such as Google Docs. This is for navigation between pages on the web. As such is does NOT use the ARIA roles of either menu or menuitem.

Hover Interaction Logic in Desktop Mode

Hover Interaction Logic Link

The design HTML for this mega menu adds the requirement for the dropdown menus to open on hover interaction when in desktop mode. To support only having hover in desktop mode, the <nav> that is the mega menu should set the attributes data-responsive-width to the minimum width (in pixels) that the desktop mode occurs. The mega-menu.js code utilizes this value when determining interactivity for any event. Do not include units when assigning the attribute.

To support accessibility, the desktop view must properly balance the interactions between opening the menus via hover or direct manipulation. To accomplish this, the mega menu should be considered as existing in one of three states:

Closed
No sub-menu in the mega menu is opened.
Hover
A sub-menu is currently opened via hover interaction (the cursor is hovering over a submenu toggle button or a submenu).
Focus
A sub-menu is open and focus is currently within the mega menu on either a link or toggle button.

The accompanying CSS and JS files track this state in the attribute data-menu-state in the <nav> element for the mega menu. In general, focus takes priority over the hover state. Once the menu enters the focus state, hover has no effect until the menu returns to the closed state. The following table describes the various state transitions the desktop mega menu should take.

Current State Interaction Result
Closed Cursor hovers over a toggle button

State changes to Hover

Set aria-expanded="true" on the hovered toggle button

Associated sub-menu is shown

Closed A toggle button receives a click event

State changes to Focus

Set aria-expanded="true" on the clicked toggle button

Associated sub-menu is shown

Hover Cursor moves from toggle button to opened sub-menu or opened sub-menu to its associated toggle button.

No changes

Hover Cursor moves from opened sub-menu or its associated toggle button to a different toggle button

State remains Hover

Set aria-expanded="false" on the previously opened toggle button and hide the opened sub-menu

Set aria-expanded="true" on the newly hovered dropdown button and show the associated sub-menu

Hover The toggle button with aria-expanded="true" experiences a click event

State changes to Focus

No other changes

Hover A link in the opened sub-menu receives focus

State changes to Focus

No other changes

Focus

User clicks on a non-interactive part of the opened sub-menu

State changes to Focus

Focus is moved to the opened sub-menu's toggle button

Hover Escape key is pressed

State changes to Closed

The relevant toggle buttons sets aria-expanded="false"

The opened sub menus closes

Focus Escape key is pressed

State changes to Closed

All toggle buttons set aria-expanded="false"

Any opened sub menus disappear

If focus was within a sub-menu, focus is moved to the toggle button associated with the sub-menu

Focus A toggle button or opened sub-menu is hovered over

No changes

Focus The toggle button with aria-expanded="true" receives a click event

State changes to Closed

Toggle button sets aria-expanded="false"

Opened sub-menu is closed

Focus A toggle button with aria-expanded="false receives a click event

State remains Focus

Set aria-expanded="false" on the previously opened toggle button and hide the opened sub-menu

Set aria-expanded="true" on the newly hovered dropdown button and show the associated sub-menu

Focus

Focus moves to any part of the mega menu: links in an opened sub-menu or any toggle button.

No changes

Focus

Focus moves outside of the mega menu

State changes to Closed

Toggle button sets aria-expanded="false"

Opened sub-menu is closed

Focus

User clicks on a non-interactive part of the opened sub-menu.

State remains Focus

Sub-menu remains open

Focus remains where it was

Focus

User clicks outside of the opened sub-menu on a non-interactive element.

State changes to Closed

Toggle button sets aria-expanded="false"

Opened sub-menu is closed

Focus is moved to the browser's default

Focus

User moves to a different browser tab or application.

State remains Focus

Sub-menu remains open

Focus remains where it was

Keyboard Support Logic

Keyboard Support Link

For keyboard support, the mega menu should provide the following interactivity in both mobile and desktop settings:

Key Function
Tab or
Shift + Tab
Move keyboard focus among top-level buttons, and if a dropdown is open, move the focus into and through the links in the dropdown.
Space If focus is on a disclosure button, activates the button and toggles the visibility of the dropdown.
Enter

If focus is on a disclosure button, activates the button and toggles the visibility of the dropdown.

If focus is on a link, activates the focused link.

Escape If a dropdown is open, closes it. If the focus was within the opened dropdown, set focus on the button that controls that dropdown.

Although the disclosure pattern lists the arrow keys, Home, and End keys as optional means of interactions, we do not recommend their use here. These interaction options are not implemented consistently. If they are to be added, we would need to make sure ALL disclosures on library sites also provide them.

Additionally, space and enter natively triggers the click event for buttons, and enter natively triggers click for links (i.e., <a>). No keyboard event listeners are needed for them.

In terms of ARIA support, the only required bit of ARIA is aria-expanded="true/false" on the toggle buttons for the dropdown menus and for opening the responsive mode menu button. For each such button, aria-expanded should be set to false if the associated dropdown menu is closed. Whenever the associated menu is opened, whether by hover or click, the value should be set to true.

The disclosure pattern does suggest two additional ARIA attributes: aria-controls and aria-current but neither are recommended here. The first, aria-controls, is not widely supported by screen readers currently due to difficulties in implementation. Current recommended practice based on testing suggests that aria-controls either provides no benefit or causes additional problems and should thus be avoided.

aria-current is well supported among screen readers currently. Setting aria-current="page" on a link will inform screen readers that the link is to the page the browser is currently at. CSS can then be used to indicate that as well to sighted users. Its utility, however, is debatable in a dropdown menu situation as no indication is provided in the toggle buttons. Therefore, adding the code to support and properly update its usage is not required or recommended for this mega menu in either desktop or responsive mode.

Additional Features for Accessibility

Additional Features for Accessibility Link

In addition to the above items, the following features are also provided to enhance the accessibility experience:

Acknowledgements

Acknowledgements Link

Much thanks go to the many fruitful conversations and feedback found on the Web A11Y slack. This project also makes use of the open source hoverintent library.