toast()
Use a toast for a brief announcement
(saved, sent, deleted). For the currently active top status that
stays visible until it's resolved (offline, sync error, missing assignment)
use <ui-statusbar> with the
notifications store —
the statusbar displays the highest-priority item inline with role="status"
so screen readers hear it; <ui-notifications>
lets users open a popover containing all notifications.
| Export | Signature | Description |
|---|---|---|
toast |
toast(message, { type?, duration?, error?, action_label?, action_href?, action_callback? }) |
Shows a brief notification at the bottom of the screen; returns a function that dismisses it |
toast_timing |
{ info_ms, error_ms, action_ms } |
Configurable default durations; tests can set a duration to zero to avoid waiting |
get_history |
get_history() |
Returns an array of previous toasts (newest first) |
clear_history |
clear_history() |
Empties the history |
type: "info" (default) | "error" | "warning"
· duration: ms, default 4,000 (info) / 6,000 (error) / 10,000 (any toast with an action)
· the countdown pauses while the pointer is on the toast or focus is inside it
· duration: Infinity never auto-dismisses — use the returned function
· Event: document dispatches 'toast' with {message, type} in detail
· CSS: --toast-align stacks the chips at one end of the bottom edge (Placement)
Basic toast with default settings. Disappears after 4 seconds.
Red background, role="alert" for assertive screen-reader announcement. Disappears after 6 seconds.
Control how long the toast is shown with duration (ms).
Multiple toasts shown at once. Each has its own timer.
Info and error toasts can be shown at the same time.
Examples of toasts in try/catch flows, as in production code.
Add an action when the message suggests something the user can do. Pass action_label with action_callback for a button or action_href for a link. Supplying both creates a link that also runs the callback. The control sits inside the toast's <output> and is included in its announcement; see Accessibility.
An action toast stays visible for
10,000 ms rather than 4,000 or 6,000. The countdown pauses while the pointer is over a toast or focus is inside it, giving users time to reach the action.
The action inherits the toast's text color through currentColor. The default toast has a contrasting background, while
error and warning use dark red and orange backgrounds in both themes. currentColor keeps the action and its focus ring legible on all three.
Do not apply .btn styles to toast actions: they are designed for page surfaces and can lack contrast here. For example, an .outline button uses --text-1 for its label, matching the default toast's background.
For an action the user should still be able to reach after the toast has gone, raise it
through the notifications store as
well — it publishes the same three option names, so both can use the same options object.
All toasts are saved to a history (max 50). Listen to the document event
'toast' for real-time updates. An entry keeps action_label
when one was supplied. The action handler is no longer available after dismissal, so only its label is recorded; message remains unchanged because callers compare it directly.
| Type | Message | Action | Time |
|---|
Chips stack in a lane across the bottom edge of the viewport, centred, with the newest
at the bottom. A page sets --toast-align to stack them at one end of that
lane instead — flex-end for the trailing corner, flex-start
for the leading one. Each chip gets a full-width row inside the lane, and the property
is that row's justify-content, so any justify-content value
works and center is the default.
Set it wherever the container inherits from, which is anywhere above
<body>:
Use it when the page keeps a control on the bottom edge. A centred
control is the case that needs this: the chips land on it, and because the container is
a popover in the top layer, no z-index on the control can lift it clear.
Move the stack to the end the control leaves free.
A chip wraps at a readable measure (--size-content-2, or
the lane's width when that is narrower) rather than running the lane's whole width. The
token is in ch, so the measure follows the chip's own type size. That cap is what makes
the alignment worth setting: a chip only clears a control at the opposite end of the
lane while it is narrower than the distance between them, and an uncapped one grows
straight back across it — a plain error sentence drew a single line over 1000px long
on a wide screen. Keep messages to a sentence or two; a long one still wraps to
several lines and takes up that much more of the lane.
There is no property for the other axis, and that is deliberate. The
enter animation wipes each chip upwards out of the lane's bottom edge: its wrapper grows
from zero height with the chip pinned to the wrapper's rising top edge, so the wrapper's
own overflow: hidden reveals it from the bottom up. The clip is local, so a
lifted lane would still animate — but the wipe reads as motion because the edge it
emerges from is the screen's. Away from that edge the same animation looks like a chip
materialising out of an invisible seam, and giving it an edge again means a second clip
supplied by the page. Keep the stack on the bottom edge and move it sideways.
The container is a popover="manual" element with role="status",
aria-live="polite" and aria-atomic="true"; an
error toast additionally carries role="alert" and
aria-live="assertive" on its own <output>. Roles are set
when the element is created and never flipped afterwards — screen readers handle a
runtime role change inconsistently.
activeElement is unchanged
when a toast appears and disappears.
<body>, so it joins the focus order there — past the page's own
content. Once the action receives focus, the countdown pauses. There is no shortcut
that jumps focus into the region; a keyboard user who has not tabbed to the end will
use the regular interface to perform the same action. Always provide that alternative route.
<ui-icon> resolves its glyph by fetch,
and the toast measures its own height the instant it is inserted — an icon loaded later can increase the content height without updating the toast’s measured height, clipping its content. The persistent notification popover has no fixed height, so
<ui-notifications> takes an
action_icon while toasts do not.
<ui-statusbar> avoids by narrowing its live region.
currentColor, not the shared
--brand ring, and it fits inside the chip's own block padding — the toast
wrapper clips its overflow, so a ring drawn outside the chip would be cut off.