ARIA Roles and Labels

Fill accessibility gaps that native HTML can't express on its own.

ARIA (Accessible Rich Internet Applications) is a set of attributes that describe roles, states, and labels to assistive technology. It's powerful — and easy to misuse.

The first rule of ARIA

The official first rule is: don't use ARIA if a native element already does the job. A real <button> beats <div role="button"> every time, because the native element brings focus, keyboard, and semantics for free. Reach for ARIA only to fill genuine gaps.

The attributes you'll actually use

  • aria-label — gives an element an accessible name when there's no visible text (think an icon-only button).
  • aria-labelledby — names an element by pointing at the id of visible text.
  • aria-describedby — links to extra descriptive text, like a hint under a field.
  • aria-live — announces content that changes dynamically, such as a status message.
  • aria-hidden="true" — hides decorative content from screen readers.
<button aria-label="Close dialog">×</button>

That single label turns a meaningless × into a button a blind user can understand.

Example

Try it yourself
Loading editor…
Press Run to see the result.

When to use it

  • A developer adds aria-label="Close dialog" to an icon-only X button so screen reader users know its purpose.
  • A custom dropdown menu uses role="listbox" and role="option" with aria-selected so assistive technology treats it as a native select.
  • A loading spinner uses aria-live="polite" so screen readers announce when an async operation completes.

More examples

Aria-label for an icon button

aria-label provides an accessible name when visible text is absent; aria-hidden hides the decorative SVG.

Example · html
<button aria-label="Close notification">
  <svg aria-hidden="true" focusable="false" width="16" height="16">
    <line x1="0" y1="0" x2="16" y2="16" stroke="currentColor">
    <line x1="16" y1="0" x2="0" y2="16" stroke="currentColor">
  </svg>
</button>

Live region for status updates

role="status" with aria-live="polite" announces dynamic content changes to screen readers without moving focus.

Example · html
<div role="status" aria-live="polite" aria-atomic="true" id="status">
  <!-- Updated dynamically by JS -->
</div>

<button onclick="document.getElementById('status').textContent='File saved successfully.'">
  Save
</button>

Aria-expanded for accordion toggle

aria-expanded signals the open/closed state of the controlled panel to screen reader users.

Example · html
<button
  aria-expanded="false"
  aria-controls="panel-1"
  id="btn-1"
  onclick="
    const btn = this;
    const open = btn.getAttribute('aria-expanded') === 'true';
    btn.setAttribute('aria-expanded', !open);
    document.getElementById('panel-1').hidden = open;
  ">
  Show details
</button>
<div id="panel-1" hidden>
  <p>Expanded content goes here.</p>
</div>

Discussion

  • Be the first to comment on this lesson.