Lesson 15 · Part 4 · WAI-ARIA 1.3

The ARIA model

ARIA is a set of attributes that tell assistive technology what something is when HTML cannot say it. It adds a role, a name and a state. It adds no behaviour: role="button" does not listen for Enter or Space. You still have to.

In one minute

In plain words

ARIA is a name tag, not a skill. Pinning a "Lifeguard" tag on someone does not teach them to swim. Everyone now expects them to rescue people, and when they cannot, it is worse than no tag. Put the tag only on things that can do the job.

1. The first rule: use the native element

A native element gives you a role, a name, keyboard support and a focus ring without a single aria-* attribute. A div with a role gives you only the role. Try to rebuild a button by hand: tick each fix and see what is still missing. Then use the real element.

Step 1. Choose the element, then press Tab to the control and try Enter and Space.

Patches to add to the div

Nothing pressed yet.


          
What works
FeatureResult

Adding role="button" to a real <button> is noise. Replacing the button with a div and a role is a regression unless you rebuild focus, activation, the name and the disabled state yourself. Use ARIA when you build a widget HTML does not have (a tablist, a combobox, a tree), or when you must expose a state HTML cannot, such as aria-expanded on a disclosure that is not <details>. Lessons 16 to 21 cover those cases.

2. Name, role and value

Assistive technology does not read your CSS. It reads the accessibility tree: a simplified copy of the page that the browser builds from the DOM. In that tree each control should answer three questions.

This is WCAG 4.1.2 Name, Role, Value. Below is a hand-made checkbox. Click it, and compare "visual only" with "visual plus aria-checked".

Step 2. Choose how the script behaves, then toggle the box with Space or a click.


          

A native <input type="checkbox"> keeps picture and state in sync by itself. A custom one makes you do it.

3. The host language wins, until you override it

The host language is HTML. A <button> already has the role button. A <nav> is a navigation landmark. The role attribute can override that, so you must be careful. Pick a snippet and see what the tree gets.

Step 3. Choose a snippet.


          

role="none" and role="presentation" strip semantics. Use them on a container whose children carry the real meaning, never on a focusable control.

Presentational children

Some roles hide their own children from the tree: button, checkbox, img, math, menuitemcheckbox, menuitemradio, option, progressbar, radio, scrollbar, separator, slider, switch and tab. A heading inside a role="button" is just text. Do not use aria-owns on these to rescue the children. If you need the children exposed, you picked the wrong role.

4. Abstract roles are not for pages

The ARIA specification keeps a family tree of roles so they can inherit properties from each other. The top-level "parent" roles are abstract: they exist only for that model. You must not use them in HTML. Type a role to test it.

Step 4. Type a role name, or pick an example.


Abstract roles: command, composite, input, landmark, range, roletype, section, sectionhead, select, structure, widget, window.

role="widget" does nothing useful for a screen reader. Pick a concrete role from lessons 18 to 20 instead.

5. Implicit values and explicit attributes

Many properties have a default. If you leave the attribute off, assistive technology uses that default, it does not treat it as "unknown". Some roles change the default. Orientation is a good example: arrow keys follow it.

Implicit aria-orientation by role
RoleDefault orientation
slider, separator, tablist, toolbar, menubarhorizontal
scrollbar, listbox, menu, treevertical

Set the attribute explicitly whenever the user can change the state, or whenever your layout differs from the default. That way your script and the tree cannot drift apart.

6. What ARIA never does

Most ARIA bugs come from believing ARIA does more than it does. Choose a claim and see whether it is true.

Step 5. Choose a claim.

Common mistakes

Common ARIA model mistakes
You seeWhy it is a problemFix
<div role="button"> with no handlerAnnounced as a button, does nothing from the keyboard.Use <button>.
<button role="button">Redundant noise.Remove the role.
<a href role="button">Looks like a button, but Space does not work.Pick one: link or button.
role="widget"Abstract role. Ignored.Use a concrete role.
Script updates visuals onlyThe tree reports the old state.Update the attribute in the same function.
Accessible name differs from the visible labelVoice-control and screen reader users meet different interfaces.Keep them identical (WCAG 2.5.3).
Try it yourself
  1. Open devtools, select this page's skip link, and read its role and name in the Accessibility panel. There is no ARIA on it, and the tree is still correct.
  2. In lab 1, tick only role="button" and press Tab. What is announced, and can you reach it?
  3. Find a custom widget on a site you use. Does its state change in the tree when you click it?

Remember

Edit this example in the playground