โ™ฟ Web Accessibility

ARIA Roles in Practice: When to Use Them and When to Skip Them

By Shubham Sharmaยทยท8 min read
Code editor showing ARIA attributes on a custom widget

The most accessible feature I ever shipped was one I deleted. A junior on my team had added role="button" tabindex="0" aria-pressed="false" to a <div>, plus a keydown handler for Enter and Space โ€” about 30 lines of code to reinvent what <button> does out of the box. Removing all of it and using a real <button> instantly fixed the screen-reader bug the client had reported. That's the whole story of ARIA: it's an extraordinarily powerful tool for making custom widgets accessible, and an equally powerful tool for accidentally destroying accessibility that native HTML already gave you for free. The five rules exist because I โ€” and every developer I've ever mentored โ€” have made both mistakes.

The first rule of ARIA

"If you can use a native HTML element, do that instead of repurposing an element and adding an ARIA role."
โ€” W3C ARIA Authoring Practices

<button> already has role="button", keyboard support, focus styles, and the right accessibility tree. <div role="button" tabindex="0"> requires you to reinvent all of that โ€” usually badly.

ARIA roles you'll actually use

  • role="dialog" + aria-modal="true" โ€” for modals
  • role="tablist" / "tab" / "tabpanel" โ€” for tabbed UIs
  • role="alert" โ€” for important status messages
  • role="navigation" โ€” when <nav> isn't enough

Useful aria-* attributes

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

<input aria-describedby="hint-1">
<small id="hint-1">8+ characters</small>

<span class="badge" aria-label="3 unread messages">3</span>

Common ARIA mistakes

  • role="button" on a div without keyboard handlers
  • aria-hidden="true" on focusable elements (traps screen reader users)
  • Duplicating native semantics (role="button" on a <button>)
  • Using aria-label on elements that already have visible text

Live regions for dynamic content

<div aria-live="polite" id="status"></div>
<script>
  document.getElementById('status').textContent = 'Saved.';
</script>

Frequently asked questions

Is ARIA needed for SEO?

Not directly. But good semantic HTML helps both accessibility and SEO.

Can I use ARIA on any element?

Most attributes work on most elements, but native HTML semantics usually do the job better and with less risk.

Enjoyed this article?

Share it with a fellow developer or explore more tutorials in our blog.

More articles