Toast Timing and WCAG 2.2.1

Permalink to "Toast Timing and WCAG 2.2.1"

A toast that vanishes after three seconds is a time limit. For a screen reader user who is mid-sentence in another part of the page, for a magnifier user zoomed into a table far from the corner where toasts appear, for a user with a reading disability who needs longer to read, three seconds is not enough. WCAG’s Timing Adjustable criterion was written for session timeouts and quizzes, but it applies just as much to messages that disappear on their own. The good news: a few rules make auto-dismissing toasts conform.

This guide belongs to notifications & toasts for data operations.

Spec reference

Permalink to "Spec reference"

SC 2.2.1 Timing Adjustable (A): for each time limit set by the content, at least one of these is true — the user can turn it off; adjust it to at least ten times the default; or is warned and can extend it at least ten times with a simple action. Exceptions: real-time events, essential time limits, and limits longer than 20 hours.

For toasts, the usual conforming approaches are:

  • Turn off — a setting “Keep notifications until I dismiss them”.
  • Extend — pausing on hover and focus, which stops the timer indefinitely while the user engages.
  • Content available elsewhere — if the same message is permanently available (a notification history, the updated page itself), the toast’s disappearance does not remove information. This is an interpretation widely used in practice; pair it with one of the above for safety.

SC 2.2.4 Interruptions (AAA) and SC 1.4.13 Content on Hover or Focus (AA) also bear on toasts that appear and disappear.

Reading time needed versus common toast durations Bar chart comparing typical auto-dismiss durations (3, 5 and 8 seconds) with an estimated time for a screen reader user to hear a 15-word message after finishing current speech (about 12 seconds) and for a magnifier user to find and read it (about 20 seconds). Reading time needed versus common toast durations3 s defaultcommon library default5 s defaultstill shorter than many users need8 s minimumreasonable floor for plain confirmationsScreen reader userfinish current speech, then hear the messageMagnifier userpan to the corner, then read
Short defaults fail exactly the users who most need the message.

When to use — and when not to

Permalink to "When to use — and when not to"

Auto-dismiss is acceptable for purely informational confirmations whose effect is visible elsewhere — “Filters saved”, “Row updated” — provided the timer pauses on hover and focus and a setting can turn auto-dismiss off.

Do not auto-dismiss toasts that contain actions (Undo, View, Download), warnings or errors. The action is a function; removing it on a timer is a time limit on using it. The misapplication: an Undo toast that disappears after five seconds, making undo effectively unavailable to slower users.

Can this toast auto-dismiss? Decision flow: does it contain an action? Then persist. Is it a warning or error? Then persist. Is the information also available elsewhere? If yes, auto-dismiss after at least 8 seconds with pause on hover and focus; if no, persist or add it to history. Can this toast auto-dismiss?Contains an action?Undo, View, Download, Retryyes: persist until dismissedWarning or error?anything the user must act onyes: persistAvailable elsewhere?page shows the result, or history keeps itno: persist or add historyPlain confirmationat least 8 s; pause on hover and focususer setting can disableauto-dismiss

Annotated code example

Permalink to "Annotated code example"
const prefs = { keepToasts: localStorage.getItem('keepToasts') === 'true' };  // user setting (turn off)

function scheduleDismiss(toast, kind, hasAction) {
  if (hasAction || kind === 'warning' || kind === 'error' || prefs.keepToasts) return; // persist
  const ms = Math.max(8000, words(toast.textContent) * 400);       // at least 8 s; longer for long text
  let remaining = ms, start = Date.now(), t = setTimeout(remove, ms);

  function pause() { clearTimeout(t); remaining -= Date.now() - start; }
  function resume() { start = Date.now(); t = setTimeout(remove, Math.max(remaining, 2000)); }
  function remove() { toast.remove(); }

  // Pause indefinitely while the user engages (SC 2.2.1 extend; SC 1.4.13)
  toast.addEventListener('mouseenter', pause);
  toast.addEventListener('mouseleave', resume);
  toast.addEventListener('focusin', pause);
  toast.addEventListener('focusout', resume);
}
<!-- Settings: turn the time limit off (SC 2.2.1 option a) -->
<label><input type="checkbox" id="keep-toasts"> Keep notifications until I dismiss them</label>

Keyboard & AT behaviour

Permalink to "Keyboard & AT behaviour"
Situation Expected behaviour Notes
Toast appears while a screen reader is speaking Message queued (polite) and read afterwards The toast must still exist, or the history must, when the user goes looking
User presses the toast shortcut Focus to toast; timer paused —
User tabs away Timer resumes with at least 2 s left Avoid instant disappearance on blur
“Keep notifications” enabled No toast auto-dismisses Store per user, not per device, if you can
A confirmation toast with pause and resume Timeline: toast appears at 0 seconds; the user hovers at 3 seconds and the timer pauses; they move away at 10 seconds and the timer resumes with 5 seconds left; it dismisses at 15 seconds; the message remains in history. A confirmation toast with pause and resume0 sAppears"Filters saved", 8 s timer starts3 sHovertimer paused with 5 s remaining10 sPointer leavestimer resumes15 sDismissedtoast removedLaterHistory"Filters saved, 10:42" still listed
Engagement stops the clock; the history keeps the content.

Integration context

Permalink to "Integration context"

Timing is one part of accessible toast notifications for background jobs; the history that makes auto-dismiss safe is notification centres and unread counts. Undo deserves a home beyond the toast, as discussed in confirming and undoing destructive row actions.

Gotchas

Permalink to "Gotchas"

Pausing on hover but not focus. Many libraries pause on mouse hover only. Keyboard users who reach the toast with a shortcut see it vanish under them. Pause on focusin too.

Window blur. Some libraries pause when the window loses focus, which is helpful — but they should not treat screen reader virtual cursor movement as blur.

Toasts in background tabs. A toast that fires in a hidden tab and auto-dismisses before the user returns is never seen. Start the timer when the document becomes visible.

Framework notes

Permalink to "Framework notes"

Library defaults are short: many React toast libraries default to 4–5 seconds; Angular Material’s snack bar has no default duration (persists) unless you set one; Vue Toastification defaults to 5 seconds. Raise defaults centrally and enable pause on focus:

// react-hot-toast: global defaults
<Toaster toastOptions={{ duration: 8000 }} />
// Vue Toastification
app.use(Toast, { timeout: 8000, pauseOnHover: true, pauseOnFocusLoss: true });

Verify that focus inside the toast pauses the timer — that behaviour often has to be added yourself.

Worked example

Permalink to "Worked example"

An analytics product shows “Filters saved” toasts for four seconds and “Report deleted — Undo” toasts for five. An audit flags both. The fix is three changes. “Filters saved” becomes an informational toast with an eight-second minimum that pauses on hover and focus, and it is written to history. “Report deleted” becomes an actionable toast that persists until dismissed, Undo is added to the report list’s context menu and to Ctrl+Z for ten minutes, and the deletion is recorded in history with an Undo link. A new preference, “Keep notifications until I dismiss them”, is added to the account settings. Nothing about the visual design changed; only the rules did.

Testing checklist

Permalink to "Testing checklist"

Design system notes

Permalink to "Design system notes"

Encode the classification — info, action, warning, error — in the notification API and derive timing from it. Expose the minimum duration and the “keep until dismissed” preference as platform settings, not per-call options, so individual teams cannot shorten them.

FAQ

Permalink to "FAQ"
Is any auto-dismissing toast a WCAG failure?

Not necessarily. If users can turn auto-dismiss off, or the timer pauses while they engage, or the content is available elsewhere, it can conform. Toasts with actions that disappear are the common failure.

Does pausing on hover satisfy 2.2.1?

It is a strong extension mechanism for pointer and keyboard users who reach the toast, but not for users who never reach it in time. Combine it with a history or a setting.

What duration should I use?

At least eight seconds, plus about 400 ms per word beyond twenty words. Then let users turn auto-dismiss off.

Should errors ever auto-dismiss?

No. Errors need acknowledgement or resolution; keep them until dismissed and record them in history.

Permalink to "Related"

← Back to Notifications & Toasts for Data Operations