ESC

Type to search the knowledge base.

ARIA Roles Overview

What ARIA roles do, first rule of ARIA, landmark/widget/document roles, and when native HTML already provides the role.

intermediate3 min read
  • accessibility
  • aria-roles

ARIA roles tell assistive tech what a custom element is — button, dialog, navigation, tab. They don’t implement keyboard behavior or styling. Wrong roles are worse than none: a div with role="button" that isn’t keyboard-activatable is a defect.

Docs: ARIA roles, First Rule of ARIA.

First rule of ARIA

If you can use a native HTML element with the semantics and behavior you need already built in, do that instead.

<!-- Prefer -->
<button type="button">Save</button>

<!-- Avoid unless you must -->
<div role="button" tabindex="0">Save</div>

Native elements bring keyboard, form participation, and expected AT mapping.

Role categories (practical)

Category Examples Notes
Landmark banner, main, navigation, contentinfo Prefer <header>, <main>, <nav>, <footer>
Widget button, checkbox, dialog, tab, menu Need full keyboard + state
Structure list, heading, region Prefer <ul>, <h1–6>
Live alert, status, log Dynamic announcements
Abstract command, input Don’t use in content

Landmarks

<header>…</header>
<nav aria-label="Primary">…</nav>
<main>…</main>
<footer>…</footer>

Multiple navs need unique labels (aria-label / aria-labelledby).

Widget roles need full implementation

If you set role="dialog", implement the dialog pattern. Role alone is a costume.

Related patterns:

Implicit roles

HTML Implicit role
<button> button
<a href> link
<nav> navigation
<input type="checkbox"> checkbox

Don’t redeclare redundant roles unless fixing a known browser quirk.

States and properties go with roles

<button aria-expanded="false" aria-controls="filters">Filters</button>

aria-checked, aria-selected, aria-invalid, aria-disabled — keep them in sync with real UI.

Footguns

  1. role="button" without Enter/Space.
  2. Role conflicts (<a role="button"> — pick one interaction model).
  3. Over-landmaking every <div role="region">.
  4. Using ARIA to “fix” bad HTML instead of correcting structure.

Interview out-loud answer

“Roles map elements to AT semantics. Prefer native HTML. If I use a widget role, I implement keyboard and ARIA states per APG. Landmarks structure the page; wrong roles are worse than missing ARIA.”

Role denial and fixes

If DevTools shows role generic on something you thought was a button, you used a non-semantic element. Fix the element type before sprinkling ARIA. Role denial (role="presentation") on interactive elements is almost always wrong.

Extra practice

Write a minimal demo in a scratch file or the playground: one happy path, one failure path, and one boundary input. If you cannot exhibit a bug that the pattern prevents, you do not own the concept yet — re-read the primary docs linked below and tighten the example until the failure is obvious.

Notes from real codebases

Teams that succeed here keep the rules mechanical: lint where possible, CI for the rest, and a short human checklist for what automation cannot see. Document exceptions with an owner name and a removal date so “temporary” escapes do not become permanent architecture.

Further reading

Related guides