Skip to main content

Search rules

Search all UI Guides rules by name, category, or source

interactionsARIA

aria-disabled in Composites, disabled in Forms

MUST

MUST: Use `aria-disabled="true"` — not HTML `disabled` — for unavailable menu items, toolbar buttons, tabs, tree items and listbox options: `disabled` drops them out of the tab order and the arrow-key sequence, so users never discover the option exists. `aria-disabled` only changes the announcement, so YOUR handler must make activation a no-op. Keep HTML `disabled` for form controls whose state is already inferable from context.

Keep unavailable menu items, tabs and options focusable so users can discover they exist

<li role="menuitem" tabIndex={-1} aria-disabled="true"
    onClick={(e) => { if (isDisabled) return; run(); }}>Move to…</li>

Bad

Good

Why it matters

The two spellings of "unavailable" behave completely differently, and picking the wrong one deletes information. HTML disabled makes the control unfocusable, unclickable and silent: it vanishes from the tab order, and any arrow-key handler in a composite widget is forced to skip over it, which is how a menu of six commands quietly becomes a menu of three for anyone not using a mouse.

They never learn Delete or Move to… exist, so they cannot ask why the commands are unavailable or how to unlock them. aria-disabled="true" changes only the announcement — the element stays focusable and stays in the arrow-key sequence, assistive technology announces it as dimmed or unavailable, and it is YOUR handler that must make activation a no-op (the browser will not do it for you, so an aria-disabled button without a guard in its onClick is still live).

Use HTML disabled where the state is already inferable from context — a form submit that is greyed out under a validation summary, a Next button on the last step. Use aria-disabled inside composite widgets: menu items, toolbar buttons, tabs, tree items, listbox options. Be aware of the overlap: "Never Put a Tooltip on a disabled Button" also reaches for aria-disabled in its good example, but its subject is tooltips and hover targets; this principle is about discoverability inside a composite, and it pairs with the one-tab-stop roving-tabindex rule — that arrow-key loop is exactly what disabled breaks.

Built by Gleb Stroganov, design engineer at Evil Martians.

The rules come from other people's skills and guidelines — Vercel, Rauno Freiberg, @Ibelick, impeccable, Emil Kowalski, Tailwind, RAMS — each one credited on the Sources page. The work here is extraction and wiring: every rule is pulled into one corpus, given a good and a bad example you can operate, a MUST/SHOULD/NEVER rule an agent can paste, and a link back to where it came from.