Toast
Usage
Use a toast to confirm something that happened in the background or off-screen ("Work order WO-1042 closed", "Odometer readings synced") without interrupting work. Toasts disappear on their own, so they must never be the only place important information lives.
- Errors that block the user or need a decision belong in an alert or an alert dialog, not a toast.
- Two lines at most: a title (what happened) and an optional message. One action at most ("Undo"); the same action must also be reachable elsewhere.
- No more than 3 on screen; the oldest leaves when a fourth arrives.
Anatomy
- Region —
.toast-region, top layer, bottom inline-end, labelled "Notifications", with one politerole="status" - Toast —
.toast.toast--{tone}, overlay surface with a tone bar - Icon —
.toast__icon, per tone,aria-hidden - Title and message —
.toast__title,.toast__message - Action (optional) —
.toast__action - Close —
.toast__close, "Dismiss notification"
Examples
Toasts are shown statically in each card; the button in each card sends a real one through toast().
Toast
Odometer readings synced
Work order WO-1042 closed
KX-24 assigned while overdue
Telematics sync failed
Work order WO-1042 deleted
-
Mechanic Lee Park assigned
-
Odometer readings synced
-
Work order WO-1042 closed
Newest at the bottom, nearest the screen edge; at most 3. Click the info, success and warning buttons quickly to see the real stack.
<script type="module">
import { toast } from "../js/toast.js";
toast({ tone: "success", title: "Work order WO-1042 closed", message: "Invoice sent to Northside Depot." });
toast({ tone: "info", title: "Work order WO-1042 deleted",
action: { label: "Undo", onAction: () => restoreWorkOrder("WO-1042") } });
</script>
<!-- Rendered markup (the region is created once, on first use) -->
<section class="toast-region" popover="manual" aria-label="Notifications">
<ol class="toast-region__list">
<li class="toast toast--success">
<svg class="toast__icon" aria-hidden="true">…</svg>
<div class="toast__content"><p class="toast__title">…</p><p class="toast__message">…</p></div>
<button type="button" class="btn btn--ghost btn--sm toast__close" aria-label="Dismiss notification">…</button>
</li>
</ol>
<div class="sr-only" role="status" aria-live="polite"></div>
</section>
API
| Hook | Values | Purpose |
|---|---|---|
toast({ tone, title, message, action, duration }) | JS | Shows a toast; returns { dismiss }. Tone: info (default), success, warning, danger. action = { label, onAction } |
init(root) | JS | Wires [data-toast] buttons (data-toast-tone | -title | -message | -action); safe to call twice |
.toast--info | --success | --warning | --danger | modifier | Tone of the bar and icon |
.toast__icon | __content | __title | __message | __action | __close | parts | See anatomy |
[data-state="closing"] | attribute (set by JS) | Exit transition |
| Timing | 6s · 10s with action | Paused while the pointer or focus is in the region |
Do and don't
Work order WO-1042 closed
Payment card declined
Accessibility
| Key | Behavior |
|---|---|
| Tab | Toasts are at the end of the document; their action and close buttons are reachable. While focus is inside, timers pause |
| Enter / Space | Activates Undo or Dismiss; focus returns to where it was before entering the region |
- Announcements go through one polite
role="status"node (title + message), so screen readers aren't interrupted and don't read button names. - WCAG 2.2.1 timing: at least 6s (10s with an action), paused on hover and focus, and every toast has a close button.
- The region is a labelled landmark ("Notifications") so it can be found with landmark navigation.
- Tone is shown by icon shape and words, not color alone. Reduced motion removes the slide; toasts appear and disappear instantly.
Tokens
| Custom property | Purpose |
|---|---|
--color-elevation-surface-overlay, --elevation-overlay | Surface and shadow |
--color-feedback-{tone}-icon | Tone bar and icon |
--z-toast | Stacking when the top layer isn't available |
--motion-duration-base | -fast, --motion-easing-enter | -exit | Slide in and out |
--space-2 | -4 | Gap between toasts, distance from the screen edge |