Home ARIA

ARIA roles: a vocabulary for assistive technology

ARIA roles describe what an element is to assistive technology. Native HTML elements come with implicit roles; ARIA lets authors declare a role explicitly for custom widgets.

What an ARIA role is

A role in WAI-ARIA is the semantic category an element exposes to assistive technology. Roles answer the question, “what is this element, to a screen reader?” ARIA defines roles in four super-categories: widget roles (button, checkbox, combobox, slider…), document structure roles (article, figure, list, region…), landmark roles (main, navigation, banner…), and abstract roles that group the others (and are not used in author markup).

Native HTML elements ship with implicit roles. A <button> already has the button role; a <nav> already has the navigation role. ARIA is the escape hatch for custom widgets that have no semantic native element, and a very narrow override mechanism for the rare case where the native semantics are wrong.

The First Rule of ARIA Use

The single most important rule from the WAI-ARIA Authoring Practices Guide is: prefer the native HTML element over an ARIA role. Every ARIA role is a declaration that the author will provide every state, property, and keyboard interaction the role demands. Native HTML elements come with a working baseline that has been tested against several screen-reader and browser engine combinations.

A custom <div role="button"> requires you to:

  • Give it tabindex="0" to make it focusable.
  • Handle Enter and Space keydown to activate it.
  • Move focus correctly when it is hidden or disabled.
  • Manage aria-disabled, aria-pressed, aria-busy as state changes.
  • Handle the cursor, hover, and active visual states.

A <button> does all of these for you, in every engine.

Role syntax

Roles are declared in the role attribute. Multiple roles may be specified, separated by spaces; the user agent picks the first valid one. A role is invalid if the element does not satisfy its required parent or child structure (see “required owned elements” below).

<div role="combobox" aria-expanded="false" aria-controls="lb1">
  <input type="text" aria-autocomplete="list" />
</div>
<ul id="lb1" role="listbox">
  <li role="option">Strawberry</li>
  <li role="option">Mango</li>
</ul>

Required owned elements and required properties

Most widget roles have a required structure. A listbox must contain option (and optionally group) children. A combobox must own a listbox, tree, grid, or dialog via aria-controls. Failing to provide the required structure produces a role that the user agent rejects on at least some engine + assistive-technology combinations.

Some roles require additional ARIA properties. A slider requires aria-valuenow, aria-valuemin, and aria-valuemax. A combobox requires aria-expanded to communicate open/closed state.

Browser engine and AT support

ARIA roles are exposed through the platform accessibility tree. The mapping is engine-specific:

  • Chromium (Blink) maps via the platform tree (UI Automation on Windows, ATSPI on Linux, AX API on macOS).
  • WebKit maps via the same platform APIs on macOS and via WebKit GTK accessibility on Linux.
  • Gecko maps via the same platform APIs on each OS.

For a role to “work” end-to-end, the engine must map the role, the operating system must expose it via the platform AX API, and the assistive technology must understand the resulting platform role. For roles standardised in ARIA 1.0 and 1.1, this chain is reliable. For roles added in 1.2 (mark, meter, suggestion…), check support on a per-engine, per-AT basis.

Common pitfalls

  • Role on a non-interactive element without keyboard support. role="button" on a <div> without tabindex and key handlers is worse than no role at all — it announces “button” but cannot be activated.
  • Conflicting roles. role="presentation" on a <button> strips the implicit role; the keyboard semantics also disappear.
  • Landmark spam. Wrapping every section in role="region" clutters the landmark navigation menu in screen readers.

Further reading