Accessibility Certified – Home

Navigation with submenus that does not need a mouse

Many menus only open when you hover over them. The disclosure pattern is simpler and sturdier: a button reveals an ordinary list of links.

2.1.14.1.21.4.132.4.33.2.3

Live demo

This demo is checked with axe-core without violations and fully operable by keyboard.

Try it with the keyboard: Tab, Enter, Space, the arrow keys and Escape. With a screen reader on, you hear what gets announced.

The live demo needs JavaScript. Code and requirements are below.

Keyboard interaction

Tab
Moves from button to button and through the links of an open submenu.
Enter / Space
Opens or closes the submenu.
Escape
Closes the open submenu and puts focus on its button.

When to use this pattern

For a website’s main navigation the W3C recommends the disclosure pattern, not the “menu” pattern with role="menu". The menu pattern is meant for application menus like those in desktop software and requires complex arrow-key handling. On websites, many screen reader users expect simple lists of links.

Our own main navigation at the top of this page follows the same pattern.

Roles, states and properties

  • The navigation sits in a <nav>, named with aria-label when there is more than one.
  • Each item with a submenu is a <button> with aria-expanded and aria-controls.
  • The submenu is a normal list (<ul>) of links, hidden with hidden.
  • No menu, menubar or menuitem roles for website navigation.
  • The current page carries aria-current="page".

Keyboard interaction

KeyEffect
TabMoves from button to button and through the links of an open submenu.
Enter / SpaceOpens or closes the submenu.
EscapeCloses the open submenu and puts focus on its button.

Code

HTML and JavaScript (shortened)
<nav aria-label="Main">
  <ul>
    <li>
      <button type="button" aria-expanded="false"
        aria-controls="sub-knowledge">Knowledge</button>
      <ul id="sub-knowledge" hidden>
        <li><a href="/knowledge/criteria/">Criteria</a></li>
        <li><a href="/knowledge/glossary/">Glossary</a></li>
      </ul>
    </li>
    <li><a href="/pricing/">Pricing</a></li>
  </ul>
</nav>

Common mistakes

  • Submenu opens on :hover only, so it cannot be reached by keyboard or on touch screens.
  • The top item is both a link and a toggle: one click is supposed to do two things, keyboard users only get one.
  • role="menu" without the matching arrow-key handling: screen readers switch into a mode where Tab no longer behaves as expected.
  • A submenu that closes as soon as the pointer leaves it, before it can be reached (a hover trap, see 1.4.13 Content on Hover or Focus).

Related WCAG criteria

Sources

Are your components built like this?

The free check finds many issues automatically. In the audit a person tests every component with a keyboard and a screen reader.

Free checkSee our method