menuitem
Marks an element as an actionable item inside a menu or menubar. There is no HTML equivalent — menus are an ARIA-only construct. Use this role only when you are building an actual menu (application-style); a plain navigation list should NOT use menu/menuitem.
When to use
Inside a role="menu" or role="menubar" only, and only when the menu is an application menu — the kind that mimics a desktop app’s File/Edit/View bar, with single-tab-stop, arrow-key navigation, and Esc-to-close.
A site’s top navigation is NOT a menu. Use <nav> with a <ul> of <a> links. Confusing the two is the most common ARIA mistake on the web — it traps keyboard users in arrow-key navigation when Tab would be more natural, and it tells screen readers “application menu” when the content is just links.
Sibling roles: menuitemcheckbox (for menu items that toggle) and menuitemradio (for exclusive choices inside a menu).
Keyboard + focus contract
Per the APG menu pattern:
- Tab enters and exits the menu — focus lands on the first menuitem on entry. Tab does NOT cycle through items.
- Up/Down arrows move focus between items (with wraparound).
- Right/Left open submenus / return to parent.
- Enter or Space activates the focused item.
- Escape closes the menu and returns focus to the trigger.
- Typing a letter jumps to the next item starting with that letter (typeahead).
Use a roving tabindex: only the currently-focused menuitem has tabindex="0"; the rest have tabindex="-1".
Common failures
- Using
role="menuitem"for a plain link in a site nav. Causes keyboard traps and incorrect screen-reader announcement. - Every menuitem has
tabindex="0", so Tab steps through each one. The pattern is single-tab-stop. - Submenus that open on hover but not on Right arrow.
- Escape closes the submenu but loses focus, leaving the user stranded outside the menu.
- Items missing accessible names because the icon is the only content — add
aria-label.
Example
<button id="fileBtn" aria-haspopup="menu" aria-expanded="false" aria-controls="fileMenu">
File
</button>
<ul id="fileMenu" role="menu" aria-labelledby="fileBtn" hidden>
<li role="menuitem" tabindex="0">New</li>
<li role="menuitem" tabindex="-1">Open</li>
<li role="menuitem" tabindex="-1" aria-haspopup="menu" aria-expanded="false">
Open recent
</li>
<li role="separator"></li>
<li role="menuitem" tabindex="-1">Save</li>
</ul>