ARIA in React: When Native HTML Is Not Enough

Understand ARIA in React: roles, states, and properties that make custom widgets accessible, and when native HTML is already enough.

6 min read

ARIA in React is a set of attributes that describe custom widgets to assistive technology when plain HTML cannot. React writes these as normal JSX props, and the browser turns them into the accessibility tree a screen reader consumes.

Native HTML first

Most accessibility is already built into the platform. A button announces its role and handles Enter and Space.

A label associates text with an input. A link announces navigation.

Using native elements is the first and usually only step. Before adding ARIA, check whether an existing HTML element already expresses the same meaning.

Starting from a div and bolting on a role also loses the built in keyboard behavior. The native element is both simpler and more correct.

When ARIA is needed

ARIA earns its place when you build a widget with no native equivalent. A tabbed interface, a dropdown menu, a modal dialog, or a live alert are all made from divs and buttons, so they need explicit roles and states. These widgets cannot be described by a single HTML element, so ARIA supplies the vocabulary the accessibility tree is missing.

App.jsxApp.jsx
<div role="tablist" aria-label="Account settings">
  <button role="tab" aria-selected="true">Profile</button>
</div>

The role attributes name the parts, and aria-selected reports which tab is active. A screen reader can now describe the widget, even though the browser has no idea what a tablist is.

Roles, states, and properties

ARIA splits into three categories. A role says what a widget is, a state says what is currently true about it, and a property describes its relationships to other elements.

In JSX these are ordinary props written as role and aria-*, with the same camelCase rules as any React attribute. aria-selected, aria-expanded, and aria-labelledby all work directly on the element.

No ARIA is better than bad ARIA

Wrong ARIA is worse than no ARIA. A button given role="tab" but no tablist parent, or an aria-controls that points at nothing, actively misleads assistive technology.

The safest habit is to only add ARIA when you understand the pattern you are implementing, and to test it with a screen reader afterward. Guessing at a role produces a widget that announces nonsense.

ARIA does not do your keyboard work

ARIA describes a widget, it never implements one. Marking something role="tab" does not make the arrow keys work, and marking a dialog modal does not trap focus.

The keyboard side is still your JavaScript. The accessible tabs and accessible modal walkthroughs show both halves wired together.

Rune AI

Rune AI

Key Insights

  • Prefer native elements such as button, label, and input.
  • Add role and aria-* props only for custom widgets.
  • Roles describe what a widget is, states describe its current condition.
  • ARIA does not provide keyboard behavior.
  • Incorrect ARIA is worse than no ARIA.
RunePowered by Rune AI

Frequently Asked Questions

Does ARIA add keyboard support?

No. ARIA only describes roles, states, and properties. If a custom widget needs arrow keys or Escape, you must still write that JavaScript yourself.

When should I add a role attribute?

Only when the HTML element cannot express the widget, such as a custom tab, menu, or dialog. A native button or input already has its role and should not be renamed.

What does no ARIA is better than bad ARIA mean?

Incorrect ARIA misleads assistive technology more than missing ARIA. A wrong role or a broken aria-controls relationship can hide content or announce nonsense.

Conclusion

ARIA in React is a set of attributes that describe roles, states, and properties when native HTML falls short. Reach for native elements first, add ARIA only for custom widgets, and remember that ARIA never writes your keyboard handling for you.