OverlaysFlagship guide
Accessible Menu & Menu Button
A button that opens a menu of actions or links, navigable with arrow keys.
Last verified against WCAG 2.2 and WAI-ARIA APG 1.2 on 2026-07-02.
Implementation
<button id="menu-btn" aria-haspopup="menu" aria-expanded="false"
aria-controls="actions-menu">
Actions
</button>
<!-- Menu items are real <button>s inside role="none" <li>s. They are
tabindex="-1"; focus is managed with the arrow keys, not Tab. The
menu starts hidden. -->
<ul id="actions-menu" role="menu" aria-label="Actions" hidden>
<li role="none"><button role="menuitem" tabindex="-1">Rename</button></li>
<li role="none"><button role="menuitem" tabindex="-1">Duplicate</button></li>
<li role="none"><button role="menuitem" tabindex="-1">Delete</button></li>
</ul>Required roles, states & properties
| Element | Attribute | Why |
|---|---|---|
| Trigger <button> | aria-haspopup="menu" | Tells AT this button opens a menu, so it can announce "has popup, menu" before it's even activated. |
| Trigger <button> | aria-expanded | Communicates the menu's open/closed state on the trigger itself. |
| Trigger <button> | aria-controls | Associates the trigger with the menu it opens, by id. |
| Menu container | role="menu" | Identifies the popup as a menu (not a generic list), enabling menu-specific AT navigation and the "menu" role announcement. |
| Each item | role="menuitem", tabIndex="-1" | Identifies each row as an actionable menu item; tabIndex=-1 keeps items out of the page Tab order, they're reached only via the menu's own arrow-key roving focus. |
Keyboard interaction model
| Key | Behavior |
|---|---|
| Enter / Space / Down Arrow (on button) | Opens the menu and moves focus to the first item. |
| Up Arrow (on button) | Opens the menu and moves focus to the last item. |
| Down / Up Arrow (in menu) | Moves focus to the next / previous item, wrapping at the ends. |
| Home / End | Moves focus to the first / last item. |
| Enter / Space (on item) | Activates the item and closes the menu, returning focus to the button. |
| Escape | Closes the menu and returns focus to the button. |
| Tab | Closes the menu (it is not modal) and moves focus to the next focusable element on the page. |
Focus management rules
- Opening via Down Arrow focuses the first item; via Up Arrow focuses the last item.
- Menu items use a roving tabindex (all -1), arrow keys move real focus between them directly.
- Escape or activating an item closes the menu and restores focus to the trigger button.
- Tab closes the menu without restoring focus to the trigger, it continues the page's natural tab sequence, since menus are not modal.
WCAG 2.2 success criteria mapping
| SC | Name | Level | Why it applies |
|---|---|---|---|
| 2.1.1 | Keyboard | A | All functionality is operable through a keyboard interface with no specific timing. |
| 2.1.2 | No Keyboard Trap | A | Keyboard focus can always be moved away from a component using standard navigation. |
| 2.4.3 | Focus Order | A | Focusable components receive focus in an order that preserves meaning and operability. |
| 4.1.2 | Name, Role, Value | A | For all UI components, name, role, and value are programmatically determinable; states and changes are announced. |