What is ARIA?
ARIA (Accessible Rich Internet Applications) is a W3C specification that defines HTML attributes to make dynamic web content and interactive UI components accessible to assistive technologies, especially screen readers. ARIA bridges the gap between modern web application capabilities and the information that semantic HTML alone can convey.
However, ARIA is often misused. When used incorrectly, it can degrade accessibility rather than improve it. The first rule of ARIA is: only use it when native semantic HTML is not sufficient.
The 5 golden rules of ARIA
- Prefer native HTML — Use
<button>instead of<div role="button">. - Don't override native semantics — Don't write
<h2 role="tab">. - Keyboard is mandatory — Every interactive ARIA component must be keyboard-operable.
- Don't hide focusable elements — Never use
aria-hidden="true"on visible, focusable elements. - Interactive elements need accessible names — Via text content,
aria-label, oraria-labelledby.
Three types of ARIA attributes
Roles
Define the component type: landmarks (banner, navigation, main), widgets (button, dialog, tab), structure (list, table, heading), and live regions (alert, status).
Properties
Provide additional information: aria-label, aria-labelledby, aria-describedby, aria-required, aria-haspopup, aria-controls, aria-live.
States
Reflect current state: aria-expanded, aria-selected, aria-checked, aria-disabled, aria-invalid, aria-hidden, aria-current.
Common ARIA patterns
Tabs
<div role="tablist" aria-label="Product info">
<button role="tab" aria-selected="true"
aria-controls="panel-1">Description</button>
<button role="tab" aria-selected="false"
aria-controls="panel-2" tabindex="-1">Specs</button>
</div>
<div role="tabpanel" id="panel-1">...</div>Dialog (Modal)
<div role="dialog" aria-modal="true"
aria-labelledby="modal-title">
<h2 id="modal-title">Confirm deletion</h2>
<button>Delete</button>
<button>Cancel</button>
</div>Key requirements: trap focus inside the modal, close with Escape, return focus to trigger element on close.
Live regions
<!-- Non-urgent (doesn't interrupt) -->
<div aria-live="polite" role="status">
</div>
<!-- Urgent (interrupts user) -->
<div aria-live="assertive" role="alert">
</div>Most common ARIA mistakes
- Using ARIA instead of native HTML —
<div role="button">instead of<button>. - aria-hidden on focusable elements — Creates invisible but keyboard-reachable elements.
- Redundant aria-label — Duplicating text that is already visible.
- Forgetting to update ARIA states —
aria-expandedstaying "false" when a menu is open. - Overusing aria-live — Too many live regions make navigation unbearable.
Quick reference
| Attribute | Purpose | Values |
|---|---|---|
aria-label | Invisible accessible name | Text |
aria-labelledby | Name from another element | Element ID(s) |
aria-expanded | Open/closed state | true / false |
aria-hidden | Hide from assistive tech | true / false |
aria-live | Dynamic content zone | polite / assertive / off |
aria-required | Required field | true / false |
aria-invalid | Invalid input | true / false |
aria-current | Current item | page / step / true |
Summary: ARIA is powerful but must be used carefully. Always prefer semantic HTML first. Only add ARIA when native HTML cannot convey the necessary information to assistive technologies. And always test with a real screen reader to validate your implementations.