Skip to Content
Component ExamplesARIA Menus

ARIA Menus (and Why You Probably Don't Need Them)

Site-navigation disclosures contrasted with a complete application Action Menu keyboard model and role-selection guidance

Maintained by Martin KrugerLast reviewed

ARIA menu and menubar model application commands, not ordinary site navigation. Site navigation normally uses a named <nav>, links, and a disclosure button for a submenu. Browser and assistive-technology interaction modes vary, so do not describe Tab as universally “swallowed”; instead, implement the keyboard contract promised by the selected role.

View inaccessible code
<nav> <ul role="menubar"> <li role="none"><a role="menuitem" href="/services">Services</a></li> <li role="none"><a role="menuitem" href="/contact">Contact</a></li> </ul> </nav>
View accessible code
<nav aria-label="Main"> <button aria-expanded="false" aria-controls="services">Services</button> <ul id="services" hidden> <li><a href="/consulting">Consulting</a></li> <li><a href="/development">Development</a></li> </ul> <a href="/contact">Contact</a> </nav>

Use Escape to close an open navigation disclosure and return focus to its trigger. Tab continues through the ordinary links. See Navigation Menus and Mega Menus for focused site-navigation cases.

Application Action Menu

An Edit/Duplicate/Delete command popup is a genuine application-menu use case. Its accessible side below implements one roving tab stop, Arrow Up/Down, Home/End, printable-character typeahead, Escape return, Tab closure, and code/live parity.

Actions
View inaccessible code
<div onclick="toggleActions()">Actions</div> <div hidden><div onclick="edit()">Edit</div><div onclick="remove()">Delete</div></div>

View accessible code
<button id="action-trigger" aria-haspopup="menu" aria-expanded="false">Actions</button> <ul id="action-menu" role="menu" aria-labelledby="action-trigger" hidden> <li role="none"><button role="menuitem" tabindex="0">Edit</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>
// On open: focus the first item; exactly one item has tabindex="0". // ArrowDown/ArrowUp: move and wrap. Home/End: first/last. // Printable character: move to the next item with that initial. // Escape: close and return focus. Tab/Shift+Tab: close without preventing Tab. // Activation: perform the command, close, and return focus to the trigger.
PatternExpected semantics and interaction
Generic divsNo button or menu roles and no keyboard access.
APG menu buttonA named expanded/collapsed button opens a labelled menu; focus and all documented keys follow the menu contract.

Pattern Decision

ScenarioPattern
Site navigation or mega menuNamed nav, disclosure button, ordinary links
Application commandsMenu button, menu, managed menuitem focus
A few ordinary actions where arrow navigation adds no valueDisclosure containing normal buttons

Resources