Skip to content
Now accepting new projects — limited slots available. Get started →
Design · Updated Aug 5, 2026

What is ARIA (Accessible Rich Internet Applications)?

ARIA is a set of HTML attributes that make dynamic web content accessible to assistive technologies.

What is ARIA?

ARIA (Accessible Rich Internet Applications) is a W3C specification that defines a set of HTML attributes — roles, states, and properties — that communicate the purpose and behavior of UI elements to assistive technologies like screen readers. First published as WAI-ARIA 1.0 in March 2014, the current recommendation is WAI-ARIA 1.2 (June 2023), with 1.3 in working draft as of early 2026. ARIA doesn't change visual rendering or keyboard behavior; it only modifies the accessibility tree that browsers expose to assistive tech. This matters most for custom widgets — tabs, modals, comboboxes, live regions — where native HTML semantics fall short. For example, a <div> acting as a button needs role="button" and tabindex="0" to be perceivable and operable by a screen reader user. We use ARIA on virtually every client project, but always as a supplement to semantic HTML, never a replacement.

How it works

ARIA attributes fall into three categories:

  1. Roles define what an element is: role="dialog", role="tablist", role="alert".
  2. States describe current conditions: aria-expanded="true", aria-checked="false", aria-disabled="true".
  3. Properties provide extra metadata: aria-label, aria-describedby, aria-controls.

Browsers read these attributes and update the accessibility tree — a parallel DOM representation consumed by screen readers like NVDA, JAWS, and VoiceOver.

Here's a minimal accessible disclosure widget:

<button aria-expanded="false" aria-controls="panel-1">
  Show details
</button>
<div id="panel-1" role="region" hidden>
  <p>Additional content here.</p>
</div>
const btn = document.querySelector('button');
const panel = document.getElementById('panel-1');

btn.addEventListener('click', () => {
  const expanded = btn.getAttribute('aria-expanded') === 'true';
  btn.setAttribute('aria-expanded', String(!expanded));
  panel.hidden = expanded;
});

The critical thing: ARIA only affects the accessibility tree. You still need to handle keyboard events, focus management, and visual styling yourself. A role="button" on a <div> won't respond to Enter or Space keypresses unless you wire that up. This is why the first rule of ARIA is "don't use ARIA" — if a native HTML element does the job, prefer it. A <button> already has the correct role, keyboard handling, and focus behavior baked in.

When to use it

ARIA shines when native HTML can't express what your component does. Reach for it when:

  • Building custom widgets: tab panels, tree views, comboboxes, carousels. The ARIA Authoring Practices Guide (APG) has tested patterns for each.
  • Adding live regions: aria-live="polite" or role="status" for toast notifications, chat messages, or loading indicators that update without page reload.
  • Labeling non-text elements: aria-label on icon-only buttons, aria-describedby for form error messages.
  • Single-page app route changes: announcing new page content with aria-live since there's no browser navigation event for screen readers to catch.

Don't use it when:

  • A native HTML element already provides the semantics (<nav>, <main>, <button>, <input>).
  • You're adding role="button" to an <a> tag — just use a <button> instead.
  • You're cargo-culting aria-label on elements that already have visible text — this often overrides the visible label, creating confusion.

ARIA vs alternatives

Approach What it does When to prefer
Semantic HTML Built-in roles, keyboard behavior, and accessibility Always the first choice. <button>, <dialog>, <details>.
ARIA attributes Patches accessibility info onto custom elements When no native HTML equivalent exists
CSS-only patterns Visually toggles content (:focus-within, :checked) Simple interactions, but often inaccessible to AT
Web Components + ARIA Custom elements with shadow DOM need explicit ARIA ElementInternals API (Chrome 90+) exposes internal semantics

The hierarchy is clear: semantic HTML first, ARIA second, and CSS-only tricks for progressive enhancement only when they don't break AT. On our projects, we estimate 70-80% of accessibility issues stem from missing or incorrect ARIA on custom components, not from missing native semantics. The ElementInternals API is worth watching — it lets custom elements declare default roles and states natively, reducing manual ARIA wiring in web component libraries.

Real-world example

On a recent Next.js 15 e-commerce build, the product filter sidebar used a custom multi-select combobox. Native <select multiple> was rejected for UX reasons. We implemented the APG combobox pattern: role="combobox" on the input, role="listbox" on the dropdown, role="option" on each item, aria-activedescendant tracking the highlighted option, and aria-expanded toggling on open/close. We tested with VoiceOver (macOS), NVDA (Windows), and TalkBack (Android). The result: the component passed WCAG 2.2 Level AA audit and axe-core flagged zero violations. Total ARIA-related code was about 40 lines — small investment, massive accessibility gain for the ~8% of users relying on assistive tech.

Frequently asked questions about ARIA (Accessible Rich Internet Applications)

Is ARIA the same as WCAG?
No. WCAG (Web Content Accessibility Guidelines) is a set of success criteria that define *what* accessible means — contrast ratios, keyboard operability, text alternatives, etc. ARIA is a technical spec that provides *how* — specific HTML attributes to communicate widget semantics to assistive tech. You use ARIA to help meet WCAG criteria, but ARIA alone doesn't guarantee WCAG compliance. You could use ARIA perfectly and still fail WCAG if your color contrast is wrong or your forms lack error identification. Think of WCAG as the standard and ARIA as one tool in the toolbox for meeting it.
When did ARIA become a W3C standard?
WAI-ARIA 1.0 became a W3C Recommendation on March 20, 2014. WAI-ARIA 1.1 followed in December 2017, adding roles like `feed`, `term`, and `figure`. WAI-ARIA 1.2 reached Recommendation status in June 2023, tightening up naming conventions and deprecating some rarely-used roles. As of April 2026, WAI-ARIA 1.3 is in Working Draft. Browser and screen reader support has been solid for 1.1 features since roughly 2019, though support for newer 1.2 features like the `comment` and `suggestion` roles is still uneven across assistive technologies.
What's the alternative to using ARIA?
Semantic HTML is the primary alternative — and the preferred one. Elements like `<button>`, `<nav>`, `<dialog>`, `<details>`, and `<input type="checkbox">` already carry implicit ARIA roles and built-in keyboard behavior. The first rule of ARIA literally says: don't use ARIA if you can use a native HTML element instead. For web components, the `ElementInternals` API lets custom elements declare their own default roles and form-associated behavior, reducing the need for manual ARIA attributes. In practice, though, any sufficiently complex UI — data grids, drag-and-drop, comboboxes — will need explicit ARIA. There's no way around it.
Can ARIA make an inaccessible site accessible?
Not on its own. ARIA only modifies the accessibility tree — it doesn't add keyboard handling, focus management, or visual affordances. If you slap `role="button"` on a `<div>`, screen readers will announce it as a button, but it won't respond to Enter or Space keypresses, won't appear in tab order (unless you add `tabindex="0"`), and won't have the correct `:focus` styling. Misused ARIA is actually worse than no ARIA — it creates false promises for assistive tech users. We've audited sites where incorrect `aria-hidden="true"` on content made entire sections invisible to screen readers. ARIA must be paired with correct HTML structure, JavaScript behavior, and CSS.
Get in touch

Let's build
something together.

Whether it's a migration, a new build, or an SEO challenge — the Social Animal team would love to hear from you.

Get in touch →