Skip to content
Preptima
mediumScenarioConceptMidSenior

A toast pops up saying the changes were saved, and a screen reader user hears nothing. Why, and what do you change?

Inserting a notification into the DOM announces nothing on its own. It has to land inside a live region that was already present in the accessibility tree, with politeness chosen by consequence, hidden by clipping rather than by display none.

5 min readUpdated 2026-07-29Target archetype: Big Tech, Enterprise Captive, Product Startup
Practice answering out loud

What the interviewer is scoring

  • Does the candidate know a live region must already exist in the accessibility tree before its contents change
  • Whether politeness is chosen from the consequence of the message rather than set to assertive by habit
  • That hiding the region visually is done by clipping, because display none removes it from the tree entirely
  • Whether an auto-dismissing toast carrying an action is recognised as unreachable by keyboard
  • Does the answer treat manual screen-reader verification as the only check that proves this works

Answer

Why a new element in the corner is silent

A screen reader speaks two kinds of thing. It speaks what the user encounters as they move through the page with the virtual cursor, the tab key or a rotor, and it speaks what the page explicitly pushes at it. A toast that appears in the bottom corner of the viewport is neither of those. The user's reading position has not moved, focus has not moved, and nothing in the markup asked for the text to be spoken. The visual design carries the whole message through proximity and motion, and the accessibility layer receives no equivalent signal at all.

So the first thing to say is that this is not a defect in the screen reader, and not a missing attribute on the button that triggered the save. It is a missing announcement channel. The mechanism that exists for it is the live region: a container the assistive technology watches, so that when its contents change the new text is read out without stealing focus and without the user having to go looking for it.

The container has to exist before the message does

Here is the part that catches most teams, and it is usually why the obvious fix does not work either. Adding aria-live="polite" to the toast component and rendering that component on demand still announces nothing reliably, because the region and its text arrive in the same DOM mutation. Assistive technology monitors regions it already knows about and reports changes to their contents. A container that appears fully populated is a new node in the tree rather than a changed region, and whether anything gets spoken then depends on the pairing of browser and reader rather than on your code.

The shape that works is a permanently mounted, empty container near the root of the application, present from first render for the whole session, into which you write text when there is something to say. In a component framework that means the region lives outside the toast list and above the router, not inside the component that owns the notification.

// Mounted once for the life of the app, empty, and never unmounted.
// Announcements happen by writing text INTO it, never by mounting it.
<div aria-live="polite" aria-atomic="true" className="visually-hidden" />

Two smaller consequences follow from the same rule. Clearing the region before writing the next message avoids the case where identical text is written twice and the second write is not a change at all. And keeping the region out of any subtree you render conditionally matters more than it sounds, because a route transition that unmounts and remounts the region puts you back to announcing from a brand-new node.

Politeness is a decision about consequence

aria-live="polite" queues the text and speaks it when the user pauses, which is right for almost everything. assertive interrupts whatever is being read mid-word, and that is right only when not hearing the message immediately costs the user something they cannot recover, such as a submission that failed and discarded their input. Teams reach for assertive because it feels more reliable, and the effect on somebody working through a long form is that every background update talks over their reading.

The two roles worth knowing express the same intent with better defaults. role="status" behaves as a polite region and role="alert" as an assertive one, and both tend to be handled more consistently across browser and screen-reader combinations than a bare attribute on an arbitrary element. aria-atomic="true" tells the reader to speak the whole region rather than only the changed fragment, which is what you want for a single sentence and not what you want for a log where only the newest line matters.

If you find yourself wanting several assertive regions on one page, that is a signal to reconsider the design rather than the attributes, because only one thing can genuinely be urgent at a time.

Hiding it without hiding it

The visible toast already shows the message, so the live region is often a parallel, invisible copy, and the way you hide it decides whether it works at all. display: none, visibility: hidden and the hidden attribute all remove the element from the accessibility tree, so a region hidden by any of them announces nothing however correct its attributes are. The technique that keeps the node in the tree while removing it from the visual layout is the clipping approach: absolute positioning, collapsed to roughly a pixel, with overflow clipped, so the element is still rendered as far as the engine is concerned.

The same reasoning explains a mistake in the other direction. If the visible toast markup itself sits inside the live region, and that markup contains an icon with alternative text, a heading and a dismiss button, the reader announces all of it, including the word "button". Writing a plain sentence into a separate hidden region gives you exact control over what is spoken.

The toast that disappears before anyone can use it

Announcement is only half the problem. If the notification contains an action, most often Undo, then a live region does not save you, because nobody can tab to something that was removed from the DOM after a few seconds. A keyboard user who hears "changes saved, undo available" and reaches for the tab key finds nothing there. Somebody using screen magnification may not have finished locating it. A user who reads slowly, or who was interrupted, gets no second chance at all.

The defensible options are to not auto-dismiss anything that carries an action, to make the same action reachable somewhere permanent such as the record itself or a notifications panel, or to put the confirmation inline beside the control that caused it, where the user's attention already is. An inline confirmation next to the save button is frequently a better design for everybody than a toast plus a hidden region, and it needs no ARIA at all.

Proving it works

None of this is detectable by an automated audit. A page whose live region mounts on demand, or whose region is hidden with display: none, passes every rule an accessibility linter has, because the markup is valid and the attribute is present where the rule looks for it. The only check that proves the behaviour is switching a screen reader on, triggering the action and listening, ideally with more than one browser and reader pairing, since tolerance for awkward cases such as late-mounted regions differs between them.

The announcement channel is the region, not the message. Mount an empty live region once for the session and write text into it, choose polite unless the user genuinely cannot afford to miss it, and never put an action inside something that vanishes on a timer.

Likely follow-ups

  • Two notifications arrive within a second of each other. What does the user hear, and what would you do about it?
  • When is moving focus to the notification the right choice instead of announcing it, and what do you owe the user afterwards?
  • How would you tell a screen reader user that a client-side route change happened, and is a live region the right tool there?
  • Your toast has an Undo button that disappears after five seconds. What is the accessible design instead?

Related questions

Further reading

accessibilityarialive-regionsscreen-readersnotifications