HTMLARIA States & Properties

ARIA States and Properties

Beyond role, ARIA defines a set of attributes that describe an element's accessible name, relationships, and current state. These fall into two categories: properties, which are mostly static, and states, which change as the user interacts with the page.

Properties vs states

Category

Behavior

Examples

Properties

Describe essential characteristics, rarely change once set

aria-label, aria-labelledby, aria-describedby

States

Describe current conditions, expected to change dynamically

aria-expanded, aria-hidden, aria-checked, aria-disabled

aria-label and aria-labelledby

Both provide an accessible name for an element that either has no visible text, or whose visible text isn't descriptive enough on its own.

HTML
<!-- aria-label: an inline string, when there's no visible text to reference -->
<button aria-label="Close dialog">&times;</button>

<!-- aria-labelledby: points to the id of another element that IS the label -->
<h2 id="billing-heading">Billing Address</h2>
<section aria-labelledby="billing-heading">...</section>
  • aria-label overrides any visible text content — use it only when there truly is no visible label.

  • aria-labelledby references one or more existing element ids, and is preferred when a visible label already exists.

  • aria-labelledby can combine multiple ids (space-separated) to build a compound label.

aria-describedby

Points to an element containing supplementary description — read after the accessible name, useful for hints, help text, or error messages.

HTML
<label for="pwd">Password</label>
<input id="pwd" type="password" aria-describedby="pwd-hint" />
<p id="pwd-hint">Must be at least 8 characters.</p>
aria-hidden

HTML
<!-- Decorative icon, redundant with visible adjacent text -->
<button>
  <span aria-hidden="true">🗑️</span>
  Delete
</button>

aria-hidden="true" removes an element (and its descendants) from the accessibility tree entirely — assistive technology skips it completely, even though it's still visible on screen. Use it for purely decorative icons, or duplicated content that would otherwise be announced twice.

aria-expanded

HTML
<button aria-expanded="false" aria-controls="menu">Options</button>
<ul id="menu" hidden>...</ul>

Announces whether a collapsible control (a menu button, an accordion header, a disclosure triangle) is currently open or closed. Toggle it in JavaScript alongside the actual show/hide logic.

aria-live regions

HTML
<div aria-live="polite" id="status"></div>
<div aria-live="assertive" role="alert" id="error"></div>

Value

Behavior

polite

Announced when the screen reader is next idle — for non-urgent updates like "Saved" or a filtered result count

assertive

Announced immediately, interrupting whatever the screen reader is currently saying — for urgent errors

off

The default — changes to this region are not announced

aria-live regions must exist in the DOM before content changes inside them — inserting the whole element and its new text at once is often missed by screen readers, which need to already be "watching" the region.

Tip
A practical rule of thumb: aria-label/aria-labelledby/aria-describedby answer "what is this and what does it do," while aria-expanded, aria-checked, aria-hidden, and aria-live describe "what is happening right now" — keep states in sync with real UI changes via JavaScript.
Note
Every ARIA attribute value must stay accurate. A stale aria-expanded="false" on a menu that is actually open is worse than no attribute at all, since it actively misinforms assistive technology users.