NavigationMenu -- Accessibility
Keyboard
| Key | Action |
|---|---|
Tab / Shift+Tab | Move focus between top-level menu items. |
Enter / Space | Activate a link or toggle a trigger's dropdown content. |
ArrowDown | Open the content panel when a trigger is focused. |
ArrowLeft / ArrowRight | Move focus between sibling menu items. |
Escape | Close the currently open content panel and return focus to its trigger. |
Home | Move focus to the first menu item. |
End | Move focus to the last menu item. |
ARIA
- The root
NavigationMenurenders inside a<nav>element, providing an implicitrole="navigation"landmark. NavigationMenuListusesrole="menubar"to group top-level items.- Each
NavigationMenuTriggerhasaria-expandedreflecting whether its content panel is open. NavigationMenuContentis associated with its trigger viaaria-controlsandaria-labelledby, so screen readers announce which trigger owns the content.NavigationMenuLinkuses standard anchor semantics. Applyaria-current="page"on the link that matches the current route.
Focus management
- When a trigger opens its content panel, focus remains on the trigger. Users
can
Tabinto the content to reach links inside. - Pressing
Escapecloses the panel and restores focus to the trigger. - The content viewport is positioned and layered so focus order flows naturally from the trigger into the panel content and back.
Active link indication
- Use
aria-current="page"on the active link so screen readers announce it as the current page. - Visual active state (underline, bold, or color change) should accompany the ARIA attribute for sighted users.
Mobile considerations
- Touch targets should be at least 44x44px.
navigationMenuTriggerStyle()provides adequate padding by default. - On narrow viewports, consider replacing the horizontal menu with a hamburger/drawer pattern. The keyboard contract remains the same inside the drawer.
- Dropdown content panels should not overflow the viewport. Use
align="start"oralign="end"onNavigationMenuContentwhen near screen edges.
Native (React Native)
- Renders as a horizontal
ScrollViewwithPressableitems. - No animated viewport -- content renders inline below the trigger.
Best practices
- Keep top-level items to 5--7 for cognitive load.
- Use
NavigationMenuLinkwithasChildfor proper anchor semantics when wrapping framework-specific link components (e.g., Next.jsLink). - Mark the current page with
aria-current="page". - Provide a visible indicator (not just color) for the active link to meet WCAG 1.4.1 (Use of Color).