Rule 1: Prefer native HTML
If a native element (<button>, <a>,
<input type="checkbox">) does what you need, use it. Native elements ship with keyboard behavior, focus
management, and screen-reader semantics for free.
Rule 2: Do not change native semantics
Never write
<h1 role="button">. If you need a button that looks like a heading, use a real
<button> and style
it.
Rule 3: All interactive ARIA controls must be keyboard operable
A
role="button"
on a div requires
tabindex="0",
an Enter/Space handler, and disabled/pressed state logic. If you can't commit to
all three, don't use the role.
Rule 4: Do not use role="presentation" or aria-hidden="true" on focusable elements
Hiding a focusable element from assistive tech but leaving it in the tab order creates a phantom focus stop that confuses everyone.
Rule 5: All interactive elements must have an accessible name
Buttons, links, and form controls need a name — via text content,
aria-label, or
aria-labelledby.
Icon-only buttons are the most common failure.
When ARIA is worth it
ARIA earns its keep for widgets HTML doesn't provide: tabs, tree views,
comboboxes, live regions, dialogs pre-<dialog>. Follow the
ARIA Authoring Practices Guide
patterns exactly — do not invent variations.
