Accessibility

a11y/menu-not-for-site-nav

Site navigation is a nav with a list of links and disclosure buttons, not role="menu" or role="menubar".

moderatestaticWCAG 4.1.2 · Afe-a11y-menus

Why

role="menu" tells screen readers to expect an application menu: arrow keys move, Tab leaves, items are commands. Website navigation built that way usually lacks the arrow-key code, and it hides that the items are links, so people cannot list or open them as links. The APG has a menubar example for navigation, but recommends the disclosure pattern as the simpler fit for most sites.

Fix

Use <nav aria-label="Main"> with <ul> and <a href>; mark the current page with aria-current="page"; open sub-lists with a <button aria-expanded> (the disclosure pattern). Keep role="menu" for command menus in applications (row actions, editor toolbars) and implement its keys.

Examples

<!-- bad -->
<nav><ul role="menubar"><li role="none"><a role="menuitem" href="/">Home</a></li></ul></nav>
<!-- good -->
<nav aria-label="Main"><ul><li><a href="/" aria-current="page">Home</a></li></ul></nav>

Sources

Facts

Id
a11y/menu-not-for-site-nav
Severity
moderate
Check
static checked in the source by audit
Applies to
html angular vue svelte astro jsx
WCAG 2.2
4.1.2, level A
Taught by the skill
fe-a11y-menus Navigation, disclosures and menus
Since version
0.1.0

Rule file on GitHub

Read it in the terminal

npx github:dawidolko/frontend-skills explain a11y/menu-not-for-site-nav