What is ARIA?

ARIA: ARIA (Accessible Rich Internet Applications) is a W3C set of HTML attributes that tells assistive technology what custom UI elements are and their state.

ARIA, formally WAI-ARIA, is a set of attributes defined by the W3C that add meaning to HTML where native elements fall short. A screen reader builds its picture of a page from the accessibility tree, which the browser derives from your markup. A <button> arrives in that tree with a role, a name and keyboard behavior for free. A <div> styled to look like a tab arrives as nothing. ARIA lets you describe that div as a tab, say whether it is selected, and point to the panel it controls. It changes what assistive technology announces. It does not change behavior: no ARIA attribute adds focusability, keyboard handling or click events.

How it works

ARIA has three kinds of attributes. Each one is a promise to the user, and the script behind the element has to keep it.

  • Roles declare what an element is: role="dialog", role="tablist", role="switch", role="status". A role implies a contract, such as arrow keys moving between tabs.
  • States describe values that change with interaction: aria-expanded, aria-selected, aria-checked, aria-disabled, aria-invalid.
  • Properties describe labels and relationships that change less often: aria-label, aria-labelledby, aria-describedby, aria-controls, aria-live.

The W3C ARIA Authoring Practices Guide (APG) documents the expected roles, states and keyboard interactions for common widgets such as dialogs, menus, tabs, comboboxes and tree views. It is the reference to check when you build one yourself. A disclosure button is the smallest useful example:

tsx
<button
  type="button"
  aria-expanded={open}
  aria-controls="filters-panel"
  onClick={() => setOpen(!open)}
>
  Filters
</button>
<div id="filters-panel" hidden={!open}>
  {/* filter fields */}
</div>

Common pitfalls

The first rule of ARIA use, from the W3C, is to prefer a native element whenever one exists. WebAIM's yearly audit of the top million home pages keeps finding that pages using ARIA average more detected accessibility errors than pages without it. Incorrect ARIA is worse than none, because it tells users something false with full confidence.

  • Adding role="button" to a div without tabIndex={0} and Enter and Space handlers. It is announced as a button and cannot be operated from a keyboard.
  • Putting aria-hidden="true" on an element that contains focusable children. Keyboard users land on something screen readers claim does not exist.
  • Letting state attributes drift: an aria-expanded that stays false after the panel opens is a false statement.
  • Using aria-label on elements with no role, such as a plain span, where many screen readers ignore it.
  • Labeling icon buttons with a tooltip only. Give the button an accessible name with aria-label or visually hidden text.

How MiniDev UI uses it

Interactive primitives such as Dialog, Tabs and Accordion are built on Base UI, which applies the roles, states and keyboard handling from the APG patterns. You provide names and content. For text that only screen readers should hear, use VisuallyHidden; to let keyboard users jump past the navigation, add SkipLink as the first focusable element. Pair all of this with a visible focus style (see :focus-visible) so sighted keyboard users can follow along.

DialoguiShadcn compatible modal dialog on Base UI with a blurred backdrop, enter and exit animation, close button, header, title, description and a footer bar.npx shadcn@latest add ui.minidev.pro/r/dialog.jsonVisually HiddenuiVisually hidden wrapper that keeps content available to screen readers while hiding it on screen via sr-only. Use it for icon button labels and extra context.npx shadcn@latest add ui.minidev.pro/r/visually-hidden.json