aria-live Regions
Announce dynamic updates with aria-live polite/assertive, role=status/alert, and patterns for toasts, validation, and async results.
- accessibility
- aria-live
When content updates without a page load — toasts, validation, live search counts — screen reader users may hear nothing unless you use a live region. aria-live tells AT to announce changes in a container.
Docs: ARIA live regions, MDN aria-live.
politeness levels
| Value | Use |
|---|---|
off (default) |
No announcement |
polite |
Announce when idle — most UI updates |
assertive |
Interrupt — critical errors only |
<div aria-live="polite" aria-atomic="true" class="visually-hidden" id="status"></div>
document.getElementById('status').textContent = '3 results found';
Roles that imply live regions
| Role | Default live behavior |
|---|---|
status |
polite |
alert |
assertive |
log |
polite |
timer |
off (usually) |
<p role="status">Saved</p>
<p role="alert">Payment failed</p>
Prefer these roles when they match meaning — cleaner than raw aria-live alone.
atomic and relevant
aria-atomic="true"— read the whole region on change, not only the diffaria-relevant— which changes matter (additions,text, …); default is usually fine
Patterns
Toast
<div role="status" aria-live="polite" id="toast"></div>
Keep messages short. Don’t assertive-spam.
Form error summary
<div role="alert" tabindex="-1" id="errors">…</div>
Also move focus for WCAG error identification strategies — accessible forms.
Loading
<div role="status" aria-live="polite">Loading results…</div>
Clear or update when done.
React caveats
Live regions should exist in the DOM before content changes. Mounting a new assertive region with text in one commit can miss announcements. Pattern:
- Render empty live region always.
- Then set text content.
function LiveAnnouncer({ message }: { message: string }) {
return (
<div role="status" aria-live="polite" className="sr-only">
{message}
</div>
);
}
Sometimes a double requestAnimationFrame or clearing then setting text improves reliability across SR/browser pairs.
Footguns
- Assertive for every keystroke.
- Live region not present before update.
- Announcing huge HTML blobs.
- Duplicate announcements (status + focus + alert).
- Hiding with
display:nonein ways that remove from a11y tree incorrectly — use visually-hidden CSS that stays “visible” to AT.
Interview out-loud answer
“aria-live announces dynamic updates. polite for most status text, assertive only for critical alerts. role=status/alert are convenient defaults. The region should exist first, then get new text; keep messages short.”
Debouncing announcements
Search-as-you-type can fire live updates every keystroke — unusable. Debounce status text (e.g. 300–500ms) and announce once: “24 results for ‘cat’.” Clear the region when the user navigates away so stale messages don’t replay.
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.
Related on this site
- Accessible forms errors
- Inclusive error messages
- Focus management
- What is the accessibility tree
- Screen reader testing basics
Further reading
Related guides
- Accessible Combobox PatternBuild or evaluate comboboxes with APG keyboard behavior, aria-expanded/activedescendant, and filterable listbox pairing.
- Accessible Forms ErrorsLabel inputs, associate errors with fields, announce failures, and avoid placeholder-only forms that break accessibility.
- Accessible Menus PatternAPG menu and menubar keyboard model — arrow navigation, escape to close, aria-expanded, and when a disclosure is enough.
- Accessible Modals PatternsModal dialogs that work: focus trap, Escape, return focus, aria-modal, and why native dialog or APG patterns beat div soup.
- Accessible Names ComputationHow browsers compute accessible names from content, labels, aria-label, and labelledby — and how that powers Testing Library queries.