Accessibility

a11y/menu-keyboard

Menus implement their keys - arrows move between items, Enter activates, Escape closes and returns focus to the button.

seriousmanualWCAG 2.1.1 · Afe-a11y-menus

Why

A role="menu" turns off the screen reader's own reading keys and hands the keyboard to the page. If the page does not implement arrows, Enter and Escape, the menu cannot be used at all.

Fix

Opening with Enter, Space or Down Arrow focuses the first item (Up Arrow: the last); Up and Down move with wrapping; Home and End jump; typing a letter moves to the next item starting with it; Enter activates; Escape closes and focuses the button; Tab closes and moves on. Only one item has tabindex="0". If this is more than the use case needs, use a disclosure (button plus list of links) instead.

Examples

menu.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') { close(); button.focus() }
  if (e.key === 'ArrowDown') focusItem(index + 1)
  if (e.key === 'ArrowUp') focusItem(index - 1)
})

Sources

Facts

Id
a11y/menu-keyboard
Severity
serious
Check
manual a person reviews it; the report lists it as a checklist
Applies to
page
WCAG 2.2
2.1.1, level A
Taught by the skill
fe-a11y-menus Navigation, disclosures and menus
Since version
0.1.0

Rule file on GitHub

Read it in the terminal

npx github:dawidolko/frontend-skills explain a11y/menu-keyboard