State vs property
WAI-ARIA distinguishes states from properties by their lifecycle.
A state is dynamic — it changes during interaction (aria-expanded,
aria-checked, aria-selected, aria-pressed). A property is
relatively static — it is set once when the element is created and
typically does not change (aria-label, aria-labelledby, aria-hidden,
aria-controls). Both share the same attribute syntax; the distinction
matters for authors because state attributes are the ones you must keep
in sync with user interaction.
The most useful subset
A small subset of ARIA covers most authoring cases:
aria-label/aria-labelledby— give an element an accessible name when no visible label suffices.aria-labelledbyreferences another element by id and is usually preferable when a visible label exists;aria-labelis the inline string fallback.aria-describedby— point to extra description text (e.g., the format hint under a date input).aria-expanded— declare whether a disclosure widget is open. Required oncombobox,treeitem,buttonthat toggles a region.aria-controls— reference, by id, the region whose visibility this control toggles.aria-current— mark the active item in a set. Values arepage,step,location,date,time, ortrue/false.aria-live— declare a region whose updates should be announced. Values:polite(most cases),assertive(urgent; use sparingly),off(default).aria-hidden— exclude an element from the accessibility tree. Use only on truly decorative or duplicated content.aria-disabledvs the nativedisabledattribute — the native attribute removes the element from focus order;aria-disabledpreserves focus so the user can still discover the disabled state.
Required pairings with roles
Some roles require certain states or properties:
| Role | Required states / properties |
|---|---|
slider | aria-valuenow, aria-valuemin, aria-valuemax |
combobox | aria-expanded, often aria-controls, aria-activedescendant |
tree, treeitem | aria-expanded for branch nodes |
tablist + tab | aria-selected per tab; aria-controls per tab |
progressbar | aria-valuenow (omit for indeterminate) |
Live regions in detail
aria-live="polite" is the default for a status region. The screen
reader queues the announcement and reads it when the user is idle.
aria-live="assertive" interrupts whatever the user is reading.
role="status" is shorthand for aria-live="polite"; role="alert"
is shorthand for aria-live="assertive".
For a live region to announce, the region must be present in the DOM before its text content changes. Adding a region and its text in the same frame often does not announce. The robust pattern is to render an empty live region in the page shell and update its text content as events arrive.
Pairing names with form controls
The accessible name of a form control is computed by a precedence chain:
aria-labelledby(joined string of referenced elements);aria-label;<label for="...">(or wrapping<label>);placeholder(last resort, low priority);title(last resort).
Prefer (3) — a visible <label> is the most reliable, helps cognitive
accessibility, and works without ARIA. Use (1) or (2) only when a
visible label is impossible.
Browser engine support
The ARIA states and properties listed above are mapped to platform AX APIs by Chromium (Blink), WebKit, and Gecko. The translation to a specific assistive-technology utterance is not standardised, so the exact wording differs by AT. Authors should test announcements with at least two AT + engine combinations on each platform.
Common pitfalls
- State attribute set as boolean attribute.
aria-checkedtakes the string values"true","false", or"mixed"— not the HTML-style empty string.aria-checked=""is a bug. - Live region created at announcement time. As above, render the region in the shell.
aria-hiddenon a focused element. When focus moves to anaria-hiddenelement, AT may announce nothing or behave inconsistently. Manage focus and aria-hidden together.- Dynamic
aria-labelthat the user cannot reach with a Tab. If a control’s only label is on a parent that is not focusable, the AT may not associate the label with the control.
Further reading
- WAI-ARIA 1.2, §6.6 Definitions of states and properties.
- The Accessible Name and Description Computation 1.2 spec (ACCNAME 1.2) — defines exactly how engines turn
aria-labelledby,aria-label, and visible text into the accessible name. Differs across engines for edge cases such as the<slot>recalculation rule (resolved in 2023). - Web Platform Tests (wpt.fyi/wai-aria) reports about 88% pass-rate across Chromium, WebKit, and Gecko for the
aria-*test suite as of 2024.