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
Navigation Is Not an Application Menu
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.
Application Roles on Navigation vs. Disclosure Navigation
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.
Unsemantic Action Dropdown vs. Complete ARIA Action Menu
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.| Pattern | Expected semantics and interaction |
|---|---|
| Generic divs | No button or menu roles and no keyboard access. |
| APG menu button | A named expanded/collapsed button opens a labelled menu; focus and all documented keys follow the menu contract. |
Pattern Decision
| Scenario | Pattern |
|---|---|
| Site navigation or mega menu | Named nav, disclosure button, ordinary links |
| Application commands | Menu button, menu, managed menuitem focus |
| A few ordinary actions where arrow navigation adds no value | Disclosure containing normal buttons |