Component
Toast
A short confirmation that an action worked, with a way to undo it.
Plain-text source, for agents and clipboard use: /components/source/toast.txt
When to use it
Confirms an action whose result is not otherwise visible, such as a booking cancelled from a list or a manifest sent, and offers Undo while it is still cheap. It appears at the bottom corner, is announced politely, stays for a fixed time, and pauses while the pointer or focus is on it.
Examples
Success with Undo
As rendered in the region. The static modifier only switches off the entrance for this page.
<div class="flux-toast flux-toast--static" data-tone="success">
<span class="flux-toast__icon"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="5.5" /><path d="M5.75 8.25l1.5 1.5 3-3.5" /></svg></span>
<p class="flux-toast__message">Booking KB-104933 cancelled.</p>
<div class="flux-toast__actions">
<button class="flux-button flux-button--ghost flux-button--sm" type="button">Undo</button>
<button class="flux-toast__close" type="button" aria-label="Dismiss"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" /></svg></button>
</div>
</div>Success without an action
When there is nothing to reverse, there is no action. The dismiss button stays.
<div class="flux-toast flux-toast--static" data-tone="success">
<span class="flux-toast__icon"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="5.5" /><path d="M5.75 8.25l1.5 1.5 3-3.5" /></svg></span>
<p class="flux-toast__message">Manifest sent to Anna Jónsdóttir.</p>
<div class="flux-toast__actions">
<button class="flux-toast__close" type="button" aria-label="Dismiss"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" /></svg></button>
</div>
</div>Information
Leave data-tone off for something that started rather than finished. The mark is the info icon in the brand colour.
<div class="flux-toast flux-toast--static">
<span class="flux-toast__icon"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="5.5" /><path d="M8 7.25v3.5M8 5.25v.01" /></svg></span>
<p class="flux-toast__message">Rates for Hotel Vík are being recalculated. This takes about a minute.</p>
<div class="flux-toast__actions">
<button class="flux-toast__close" type="button" aria-label="Dismiss"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" /></svg></button>
</div>
</div>Long message
The message wraps; the icon and the actions stay on its first line. Two lines is the most a toast should need.
<div class="flux-toast flux-toast--static" data-tone="success">
<span class="flux-toast__icon"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="5.5" /><path d="M5.75 8.25l1.5 1.5 3-3.5" /></svg></span>
<p class="flux-toast__message">Departure KB-2026-09-14 moved to 21 September. Confirmations are resent to 14 passengers tonight.</p>
<div class="flux-toast__actions">
<button class="flux-button flux-button--ghost flux-button--sm" type="button">Undo</button>
<button class="flux-toast__close" type="button" aria-label="Dismiss"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" /></svg></button>
</div>
</div>Stacked
As the region shows them: the newest at the bottom, nearest the corner, and at most three. A fourth removes the oldest.
<div class="flux-toaster flux-toaster--static">
<div class="flux-toast flux-toast--static">
<span class="flux-toast__icon"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="5.5" /><path d="M8 7.25v3.5M8 5.25v.01" /></svg></span>
<p class="flux-toast__message">Rates for Hotel Vík are being recalculated. This takes about a minute.</p>
<div class="flux-toast__actions">
<button class="flux-toast__close" type="button" aria-label="Dismiss"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" /></svg></button>
</div>
</div>
<div class="flux-toast flux-toast--static" data-tone="success">
<span class="flux-toast__icon"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="5.5" /><path d="M5.75 8.25l1.5 1.5 3-3.5" /></svg></span>
<p class="flux-toast__message">Manifest sent to Anna Jónsdóttir.</p>
<div class="flux-toast__actions">
<button class="flux-toast__close" type="button" aria-label="Dismiss"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" /></svg></button>
</div>
</div>
<div class="flux-toast flux-toast--static" data-tone="success">
<span class="flux-toast__icon"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8" cy="8" r="5.5" /><path d="M5.75 8.25l1.5 1.5 3-3.5" /></svg></span>
<p class="flux-toast__message">Booking KB-104933 cancelled.</p>
<div class="flux-toast__actions">
<button class="flux-button flux-button--ghost flux-button--sm" type="button">Undo</button>
<button class="flux-toast__close" type="button" aria-label="Dismiss"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" /></svg></button>
</div>
</div>
</div>Shown from a button
data-flux-toast shows a toast when the button is pressed. Undo dispatches flux-toast-action on the button. From script, dispatch a flux-toast event with the same fields. Press more than three to see the oldest leave.
<button class="flux-button flux-button--secondary" type="button" data-flux-toast="Manifest sent to Anna Jónsdóttir." data-flux-toast-tone="success" data-flux-toast-action="Undo">Send manifest</button>
<button class="flux-button flux-button--secondary" type="button" data-flux-toast="Itinerary PDF saved to the booking." data-flux-toast-tone="success">Save itinerary</button>
<button class="flux-button flux-button--secondary" type="button" data-flux-toast="Rates for Hotel Vík are being recalculated. This takes about a minute.">Recalculate rates</button>Anatomy
| Part | Description |
|---|---|
| Region | flux-toaster, a polite live region fixed to the bottom corner. Created by the script if the page has none. |
| Icon | An info mark, or a check for success. |
| Message | One sentence naming what happened and to what: "Booking KB-104933 cancelled." |
| Action | Optional, at most one: usually Undo. |
| Dismiss | An icon button with aria-label="Dismiss". |
API
| Name | Kind | Description |
|---|---|---|
flux-toaster | class | The region, with data-flux-toaster and aria-live="polite". Optional in markup; the script adds one. |
flux-toast | class | One toast. data-tone="success" for a completed action; leave it off for neutral information. |
data-flux-toast | attribute | On a button: the message to show when it is pressed. Pair with data-flux-toast-tone and data-flux-toast-action. |
flux-toast event | element | document.dispatchEvent(new CustomEvent("flux-toast", { detail: { message, tone, action: { label, onSelect } } })). |
flux-toast-action | element | Event dispatched on a data-flux-toast button when its toast’s action is pressed. |
flux-toast__actions | class | Holds the action, a small ghost Button, and the dismiss button. |
flux-toast--static, flux-toaster--static | class | Draw a toast, or a stack, in the page flow without the entrance. For documentation only; a static region is not live. |
States
| State | Treatment |
|---|---|
| Entering | Fades in and rises by --flux-space-2 over --flux-duration-normal. |
| Waiting | Stays for --flux-toast-duration, six seconds. The clock pauses while hovered or focused. |
| Leaving | Fades out over --flux-duration-fast. At most three are shown; the oldest leaves first. |
Keyboard
| Keys | Action |
|---|---|
Tab | Reaches the action and the dismiss button in the region, which pauses the timer. |
Escape | Dismisses the focused toast. |
Accessibility
- The region is polite: the message is read after the current announcement, without moving focus.
- The region must be in the page before the first toast, or the first toast is not announced. The script creates it on load.
- Never put the only way to do something in a toast. Undo must also be reachable from the record, for anyone who misses it.
- Pausing on hover and focus gives time to read and to reach the action, as WCAG 2.2.1 asks.
Tokens
The tier-3 and tier-2 tokens this component binds to. Change the token, not the component.
- --flux-toast-width | -padding | -gap | -offset | -duration
- --flux-toast-bg | -border | -shadow | -icon | -icon-success | -icon-size
Do and don’t
Do
- Name the record: "Booking KB-104933 cancelled", not "Done".
- Offer Undo for anything destructive that can still be reversed.
- Show one toast per action, after the action has succeeded.
Don’t
- Do not use a toast for an error.
- Do not show a toast and a Note for the same event.
- Do not put links to elsewhere in a toast. It leaves before anyone gets there.