Live Region Announcer Demo — Free ARIA aria-live Toast Pattern

Live Region Announcer Demo · Forms · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Dual confirmation
A visible toast plus a hidden aria-live region carry the same message.
Correct sr-only CSS
Uses clip/absolute positioning, never display:none, so it stays announceable.
polite politeness
Waits for any current speech to finish before announcing.
aria-atomic="true"
Announces the whole message, not just the changed fragment.
Forced re-announcement
Clears then re-sets text so repeat identical messages still fire.
No focus theft
Announcing never moves keyboard focus away from the button.
Live cart counter
A visible running total mirrors what's spoken.
Zero dependencies
Plain HTML, CSS and JS — no ARIA library required.

About this UI Snippet

Live Region Announcer Demo — Toasts That Are Actually Announced

Screenshot of the Live Region Announcer Demo snippet rendered live

A visual toast that pops up, sits for two seconds, and fades away is a completely normal UI pattern — and completely invisible to a screen reader user unless the underlying element is wired up correctly. This snippet shows the two-part pattern that makes a confirmation message actually accessible: a visible toast for sighted users, plus a separate, visually-hidden aria-live="polite" region that receives the exact same message and gets announced automatically by assistive technology, with no focus change and nothing appearing on screen.

Why the toast alone isn't enough

Screen readers only announce dynamic content automatically when it lives inside a region the browser has marked as "live." A plain <div> that gets new textContent — even if it's visually obvious, colorful, and animated — is invisible to assistive technology unless it (or an ancestor) carries aria-live, role="status", or role="alert". This is one of the most common accessibility gaps in production apps: the toast looks done, ships, and passes every visual QA pass, while screen reader users never learn their action succeeded.

The sr-only pattern, done correctly

The hidden region uses position: absolute, a 1px×1px box, overflow: hidden, and clip: rect(0,0,0,0) — never display: none or visibility: hidden. Those two properties remove an element from the accessibility tree entirely, which means a live region hidden that way would never be announced at all, defeating its entire purpose. The sr-only technique keeps the element rendered (just clipped to nothing visually), so it stays fully present for assistive technology while being completely invisible on screen — the same off-screen principle used by the accessible skip-to-content link.

Forcing re-announcement of identical messages

A live region only announces when its content actually changes. Clicking "Add to cart" twice in a row would produce the exact same message string, and some screen readers won't re-announce unchanged text. The JS clears liveRegion.textContent first, then sets the new message on the next animation frame — a small but necessary trick that guarantees a fresh mutation the accessibility tree can detect, even when the words are identical to last time.

polite vs assertive

This demo intentionally uses aria-live="polite", which waits for the screen reader to finish whatever it's currently saying before announcing the new message — appropriate for a routine confirmation like a cart update. Time-critical or error messages instead want aria-live="assertive", which interrupts immediately; see the ARIA live status badge for a side-by-side comparison of the two politeness levels.

Where this pattern belongs

Any UI that confirms an action visually — form submissions, cart updates, saved-settings toasts, filter-applied banners — needs this same two-part treatment if it wants to be usable with a screen reader. Pair it with the toast notification component for the visual half, or the notification center for a persistent log of the same announcements.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to walk through exactly why a visible toast alone fails screen reader users, and how the sr-only CSS pattern differs from display:none in terms of what stays in the accessibility tree. It's also a good prompt for auditing your own toast or notification component — ask the assistant to check whether your existing implementation has a paired live region, and if not, to add one using this same clear-then-set trick for forcing re-announcement of repeated messages. You can also ask it to extend the pattern to a queue, so multiple rapid actions get announced in sequence rather than one message clobbering the next before it's spoken. Treat this less as a finished widget and more as the reference case for making any toast, banner, or inline confirmation genuinely accessible.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build an "Add to cart" button in plain HTML, CSS, and JavaScript that is accessible to screen reader users, not just sighted users.

Requirements:
- A visible toast notification that appears briefly (around 2 seconds) when the button is clicked, confirming the action with a message and an incrementing cart count.
- A separate, always-present element marked aria-live="polite" and aria-atomic="true" that receives the exact same confirmation message as the toast, so screen readers announce it automatically with no extra JavaScript speech API required.
- The live region must be visually hidden using the correct "screen-reader only" CSS technique: position:absolute, a 1px by 1px box, overflow:hidden, and clip:rect(0,0,0,0) — explicitly do NOT use display:none or visibility:hidden, since both remove an element from the accessibility tree and would make the live region silently unannounceable.
- Handle the case where the button is clicked multiple times in a row with a nearly identical message: clear the live region's text content first, then set the new message on the next animation frame, so a screen reader treats it as a fresh change and re-announces it even when the text is the same or very similar to what was just announced.
- The announcement must not move keyboard focus away from the button.
- Add a small on-page panel that displays exactly what text was just written into the hidden live region, purely so a sighted developer can verify what a screen reader would hear without needing one running.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Click "Add to cart"A green toast slides up from the bottom for about two seconds.
  2. 2
    Check the live region textThe panel below shows exactly what was written into the hidden aria-live region — the same message a screen reader would speak.
  3. 3
    Click it againThe cart count increments and a fresh announcement fires even though the message text is nearly identical.
  4. 4
    Turn on a screen readerWith VoiceOver, NVDA, or JAWS running, click the button — you'll hear the confirmation spoken with no visual toast required.
  5. 5
    Inspect the sr-only CSSNote it uses clip/position, never display:none, so the region stays in the accessibility tree.
  6. 6
    Swap in your own actionReplace the button and message with any confirmation your UI needs to announce.

Real-world uses

Common Use Cases

Cart and checkout flows
Announce add/remove/quantity changes without relying on a toast alone.
Form submissions
Confirm a save succeeded even if the visual toast is missed.
Filter and search results
Announce a result count update, similar in spirit to a live status badge; see ARIA live status badge.
Settings toggles
Confirm a preference like the dark mode toggle actually applied.
Toast component libraries
Retrofit an existing toast notification with a paired live region.
Notification centers
Feed the same announced text into a notification center log.

Got questions?

Frequently Asked Questions

Screen readers only automatically announce dynamic content inside an element marked as "live" (aria-live, role="status", or role="alert"). A plain div that gets new text, no matter how visually obvious, is silent to assistive technology unless it or an ancestor carries one of those attributes — so the toast can look completely finished while never being announced.

display:none and visibility:hidden both remove an element from the accessibility tree entirely, which means a live region hidden that way could never be announced — the exact opposite of what you want. The sr-only pattern keeps the element in the layout and accessibility tree while clipping it to a 1px box, so it is invisible on screen but still fully readable by assistive technology.

A live region only announces when its content changes. If you click "Add to cart" twice and the message string is identical both times, some screen readers won't detect a change and stay silent. Clearing textContent first, then setting the new message on the next frame, guarantees a real mutation the accessibility tree can pick up, even for repeated identical messages.

Routine, non-urgent confirmations like a cart update should use polite, which waits for any current speech to finish so it never interrupts the user mid-sentence. Reserve assertive for urgent or error conditions that truly need to interrupt immediately — see the ARIA live status badge snippet for a direct comparison of the two.

Yes — role="status" is implicitly aria-live="polite" and aria-atomic="true" in most browsers, so it is a reasonable shorthand for exactly this pattern. Explicitly setting aria-live="polite" alongside aria-atomic="true" as this snippet does is more verbose but leaves no ambiguity about the intended behavior across browser/AT combinations.