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.
