Reference guide · html-css-js · Published 2026-08-16 · 4 min read
ARIA accessibility basics
ARIA accessibility basics: what ARIA does, roles, states and properties, common patterns (tabs, modal, live regions), and what not to add.
- ·The first rule
- ·Roles, states and properties
- ·The patterns that work
The first rule: prefer native HTML
ARIA (Accessible Rich Internet Applications) is a bridge used when native HTML cannot express a widget or a state. The governing principle is: use the native element before ARIA. A <button> is a button; a <div role="button"> needs all the keyboard, focus and semantics a native button gets for free.
The practical consequence: before writing ARIA, ask whether the HTML already says it: a <nav>, a <main>, an <input>, a <dialog>. If the native element exists, changing it to ARIA usually removes accessibility by accident of losing the built-in keyboard/focus handling. The semantic HTML article is the natural prerequisite.
The three-way split
ARIA splits into three tracked categories across its spec:
- Roles: say what an element does (
role="navigation",role="dialog",role="alert",role="tab"). Prefer native semantic for most; ARIA roles are for when no native element fits (a rich widget, a live region). - States:
aria-disabled,aria-expanded,aria-pressed,aria-haspopup,aria-busy. These reflect current widget state that visual-only cues hide from a screen-reader user. - Properties:
aria-label,aria-labelledby,aria-describedby,aria-controls,aria-live,aria-hidden. These relate to how the assistive tech interprets the element.
The honest rule of thumb is a table, and the rule errs on the side of "no ARIA unless the native element does not exist":
| Intent | Native first | ARIA when needed |
|---|---|---|
| Navigation | <nav> | role="navigation" only for a wrapper that <nav> cannot name |
| Button | <button> | only for a clickable non-native that cannot be a button |
| Heading | <h1-h6> | role="heading" aria-level="N" (rare) |
| Live region (chat, toast, ticker) | -- no native | role="status" / aria-live="polite" or role="alert" |
The two label properties that matter
aria-labelprovides a name for an element that must have one but cannot be exposed in text (an icon-only button:<button aria-label="Close">X</button>).aria-labelledbyreferences visible text elsewhere on the page by ID and is the better choice whenever visible text exists; it links to real content rather than duplicating it.
Never put aria-label on an element whose text content already equals the label (violates the label-principle), and never on a <div> that cannot take focus unless the widget also has the keyboard handler.
Live regions, done right
A live region is the ARIA pattern with the most user-visible value: it announces content inserted into the page without focus. The two common verbs:
<div role="status" aria-live="polite">2 new messages</div>
role="status"implies politeness"polite"(announce after current speech, non-interrupting).role="alert"implies politeness"assertive"(announce immediately). Reserve it for genuinely urgent notices like a failed payment, not routine feedback; the moment you use it, a screen-reader user is interrupted.
Load the entire replacement string at once; injecting each character or word separately makes a screen-reader vocalize letter by letter. The accessible-forms article has the form-error pattern that complements it.
The two anti-patterns that hurt
- Excessive roles.
role="button"on dozens of<div>s plus click-only handlers is terrible; the accessibility failure is the focus/keyboard contract, not the missing ARIA. The CSS/JS accessibility article shows what falls apart. aria-hiddenmisuse.aria-hidden="true"removes content from the accessibility tree. Using it on a parent containing focusable elements hides the focus from a keyboard user, an interactive failure a screen-reader test exposes instantly. Togglearia-hiddenonly when the content is genuinely gone from rendering.
Validate
- Use the accessibility tree, not the visual page: the a11y tree view shows roles, states, and names.
- Test with the keyboard alone (Tab, Shift+Tab, Enter/Space on a
role="button"). - Run the accessibility basics review list: one live region, clear labels, no hidden interactive content.
When you are done
ARIA is a discipline of subtraction: the correct markup removes the need for most ARIA. A page that uses semantic HTML plus visible labels plus a single aria-label on an icon button belongs to the minority where ARIA is doing real work. The rule set above is the whole basis of "ARIA basics": prefer native, use the label pair correctly, and keep live regions precise. For keyboard and interaction design beyond the basics, accessible forms and the broader HTML line are the next stop.