Menu

A navigation menu lists the links to the main pages of a website and lets users move between them. Menu items can expand into submenus that group related links. A menu is typically located in the site header to provide consistent access to the pages.

Accessibility Features

  • A <nav> landmark with a descriptive aria-label identifies the menu as a specific navigation region.
  • aria-current="page" identifies the currently active page.
  • aria-expanded on the submenu trigger button communicates the expanded or collapsed state to screen readers.
  • If the submenu obscures content, it must be dismissible with Esc.
  • aria-controls points to the submenu the trigger controls.
  • <ul> identifies the menu as a list of links and communicates the total number of links to screen readers.

Without Parent Links

Menu items with submenus use a button as the trigger. Clicking the button expands or collapses the submenu.

Example

Code Snippet

With Parent Links

Items with submenus can have both a link to the parent page and a separate button that toggles the submenu. On wider screens the submenus may also expand on hover, as the separate toggle button can be harder to discover. Hover-expanded submenus must be dismissible with Esc.

Example

Code Snippet

Hamburger Menu

A hamburger menu hides the navigation behind a toggle button and is mostly used on mobile devices. It can be implemented like an expandable submenu introduced in the examples above, but is usually implemented similarly to a modal dialog.

  • The menu toggle and close buttons do not usually have visible labels and therefore rely on aria-label to provide accessible names.
  • Keyboard focus must move into the menu on open and return to the toggle button on close.
  • If the menu obscures content, it must be dismissible with Esc and/or trap keyboard focus while it is open.
    → A native <dialog> element opened with showModal() provides the focus trap automatically. If another element is used, the focus trap must be implemented manually, for example, by adding inert to other elements on the page.
  • aria-haspopup="dialog" communicates that the button opens a dialog.

Example

Code Snippet