Skip to content

ARIA basics: when to use it, and when native HTML is better

ARIA lets developers tell assistive technology what a custom control is and what state it's in. Used well, it fills real gaps. Used as a shortcut, it often makes things worse.

Updated

What ARIA is

ARIA (Accessible Rich Internet Applications) is a W3C specification. It adds attributes to HTML that describe a role (what something is), states (checked, expanded, pressed) and properties (its label, what it controls). Screen readers and voice-control software read these attributes.

ARIA changes only what assistive technology is told. It doesn't add keyboard support, focus or behavior. If you give a div role="button", it's announced as a button, but it still won't respond to Enter or Space until you write that code.

The first rule of ARIA

The W3C's own guidance puts it simply: if a native HTML element already has the meaning and behavior you need, use it instead of adding ARIA to something else. A real <button> is focusable, works with the keyboard and is announced correctly with no extra work.

<!-- Needs role, tabindex and key handling, and is still easy to get wrong -->
<div role="button" tabindex="0" onclick="openMenu()">Menu</div>

<!-- Does all of that already -->
<button type="button" onclick="openMenu()">Menu</button>

The attributes you'll meet most

  • aria-label gives an element a name when there's no visible text, such as an icon-only button. If there is visible text, the label should contain it.
  • aria-labelledby points to other text on the page that names the element, such as a heading over a dialog.
  • aria-describedby points to extra help, such as a hint or an error message under a form field.
  • aria-expanded says whether a menu or accordion controlled by a button is open. Update it when the state changes.
  • aria-hidden="true" hides decorative content from assistive technology. Never put it on something that can receive focus.
  • aria-live marks a region whose updates should be announced, like “Added to cart”. Put the region in the page before the update happens.

Common mistakes

  • Adding a role without the matching behavior, such as role="tab" with no arrow-key support.
  • Hiding a focusable element with aria-hidden, so keyboard users land on something a screen reader says isn't there.
  • Using an aria-label that differs from the visible text, which breaks voice control.
  • Leaving aria-expanded stuck on “false” after the menu opens.
  • Misspelled attributes or invalid values, which are silently ignored.
  • Adding role="presentation" or role="none" to elements that carry meaning, such as data tables.

When ARIA is the right tool

Some patterns have no complete native equivalent: tabs, comboboxes with suggestions, tree views, live status messages, and custom dialogs in older code. The W3C's ARIA Authoring Practices Guide shows the expected roles, states and keyboard behavior for each.

If you use a component library, check whether it follows those patterns before writing your own.

Practical takeaways

  1. Reach for native HTML first: button, a, input, select, details, dialog.
  2. When you add ARIA, add the keyboard behavior that goes with it.
  3. Keep states in sync with what's on screen.
  4. Test with a screen reader such as NVDA, JAWS or VoiceOver, not just by reading the code.

What Scanpoof checks, and what needs a person

Found automatically

  • ARIA attributes that aren't allowed on an element, or are misspelled
  • Roles missing attributes they require
  • Invalid ARIA values
  • Focusable elements inside aria-hidden content

Needs a person

  • Whether the role matches how the control really behaves
  • Whether states such as aria-expanded update as the page changes
  • Whether live announcements are useful and not noisy

Sources

Ready to see where your site stands?

Scan a page free, or start a 14-day trial and monitor every site daily.