Skip to content

Find what you need, instantly

Search components, ARIA roles & attributes, and WCAG criteria.

Feedback

Toast / Status messages

Non-modal, transient messages announced via ARIA live regions.

Last verified against WCAG 2.2 and WAI-ARIA APG 1.2 on 2026-07-02.

Implementation

Persistent live region, auto-dismiss after 4s, manual Dismiss control, non-modal (never steals focus).

toast-pattern.tsx
function ToastPattern() {
  const [message, setMessage] = useState(null);
  const timeoutRef = useRef(null);

  function showToast() {
    setMessage("Changes saved successfully.");
    timeoutRef.current = setTimeout(() => setMessage(null), 4000);
  }

  return (
    <>
      <button onClick={showToast}>Show success toast</button>

      {/* This node exists BEFORE any message text does — many screen
         readers only announce live-region content if the region was
         already present in the tree when the content changes. */}
      <div role="status" aria-live="polite" className="sr-only">
        {message}
      </div>

      {message && (
        <div className="toast">
          <p>{message}</p>
          <button onClick={() => setMessage(null)}>Dismiss</button>
        </div>
      )}
    </>
  );
}

Live demo

Required roles, states & properties

Required roles, states, and properties
ElementAttributeWhy
Live region containerrole="status" (implicit aria-live="polite")Announces routine, non-urgent confirmations without interrupting whatever the user is currently doing or reading.
Live region container (urgent variant)role="alert" (implicit aria-live="assertive")Reserve for genuinely urgent/error toasts — assertive announcements interrupt the screen reader's current speech, which is disruptive if overused.
Live region containerMounted persistently, content swapped via stateThe region must already exist in the DOM before text is injected — mounting the container and its content in the same paint means many AT never "discover" the region in time to announce it.
Dismiss control (if present)aria-label="Dismiss notification"An icon-only or terse dismiss control needs an explicit accessible name distinguishing it from other Dismiss/Close controls on the page.

Keyboard interaction model

Keyboard interaction model
KeyBehavior
(none — toast never receives focus)A toast must never steal keyboard focus from whatever the user was doing when it appeared.
Tab (to reach an optional Dismiss button)If a toast includes a dismiss control, it should be reachable in the natural tab order, not force-focused.
Enter / Space (on Dismiss)Dismisses the toast early, before its auto-dismiss timer elapses.

Focus management rules

  • A toast never receives focus on appearance and never traps focus — it is non-modal by definition.
  • The live-region container is mounted once, persistently, for the lifetime of the page; only its text content changes.
  • If a Dismiss control exists, it sits in the natural tab order near where the toast renders, not force-focused.
  • Dismissing (manually or via timeout) does not move focus anywhere — the user's focus was never disturbed in the first place.

WCAG 2.2 success criteria mapping

WCAG 2.2 success criteria that apply to this component
SCNameLevelWhy it applies
4.1.3Status MessagesAAStatus messages can be programmatically determined via role or properties (e.g. aria-live) without receiving focus.

References