Toast
A toast is a short message about something that just happened, such as “Draft saved”, that
doesn’t interrupt the user. toast() shows one, from any framework or from plain JavaScript, and
<gui-toaster> is where the toasts appear: an empty element you put in the page once.
import { GuiButton, GuiToaster } from '@golemui/gui-components/react';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
export function ToastBasic() { return ( <> <GuiButton id="save-draft-button" label="Save draft" variant="outlined" onClick={() => toast({ message: 'Draft saved.', variant: 'success' })} /> <GuiToaster /> </> );}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';
@Component({ selector: 'app-toast-basic', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <gui-button id="save-draft-button" label="Save draft" variant="outlined" (click)="save()" ></gui-button> <gui-toaster></gui-toaster> `,})export class ToastBasicComponent { save() { toast({ message: 'Draft saved.', variant: 'success' }); }}<script setup lang="ts">import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
function save() { toast({ message: 'Draft saved.', variant: 'success' });}</script>
<template> <gui-button id="save-draft-button" label="Save draft" variant="outlined" @click="save" ></gui-button> <gui-toaster></gui-toaster></template>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
@customElement('toast-basic')export class ToastBasic extends LitElement { protected override createRenderRoot() { return this; }
private save() { toast({ message: 'Draft saved.', variant: 'success' }); }
override render() { return html` <gui-button id="save-draft-button" label="Save draft" variant="outlined" @click=${this.save} ></gui-button> <gui-toaster></gui-toaster> `; }}<gui-button id="save-draft-button" label="Save draft" variant="outlined"></gui-button><gui-toaster></gui-toaster>
<script type="module"> // In your app: import { toast } from '@golemui/gui-components/toast'; import { toast } from 'https://cdn.jsdelivr.net/npm/@golemui/gui-components@2.1.0/toast/+esm';
document.querySelector('#save-draft-button').addEventListener('click', () => { toast({ message: 'Draft saved.', variant: 'success' }); });</script>The demos on this page import toast() from a CDN, since a snippet in the browser can’t import
a package by name. In your app, import it from the package as the comment shows.
The entry point is @golemui/gui-components/toast, which exports toast() and registers
<gui-toaster>. To install the package and load the stylesheet, see
Installation.
Render one <gui-toaster> in the page, usually at the end of your app’s layout, then call
toast() from anywhere:
<gui-toaster></gui-toaster>import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
toast({ message: 'Draft saved.', variant: 'success' });Render the toaster up front, not when the first toast comes: screen readers only announce what
changes in a live region that is already in the page. A toast sent before the toaster connects
waits for it, and on the server toast() does nothing, so you can call it from code that also
runs there.
In React, render <GuiToaster /> once. In Angular, Vue and Lit, render <gui-toaster> in your
root template. Each example below shows all four.
The toast() options
Section titled “The toast() options”toast() takes an object, and returns a handle with the toast’s id and a dismiss() method
that closes it, or takes it out of the queue.
| Option | Type | What it does |
|---|---|---|
message | string | The text of the toast. Required. |
title | string | A short heading above the message. |
variant | 'default' | 'info' | 'success' | 'warning' | 'error' | The intent it shows, as on gui-alert. An error is announced at once. |
duration | number | Milliseconds on screen, 5000 by default. Infinity keeps it until the user closes it, the default for an error and for a toast with an action. |
action | { label: string; onAction: () => void } | A button in the toast that runs onAction, then closes it. |
id | string | Names the toast. A toast with the id of one on screen replaces it. |
toaster | string | The id of the gui-toaster to show it in. Defaults to the first one in the page. |
onDismiss | (reason) => void | Runs when the toast closes, with why: 'timeout', 'close', 'escape', 'action' or 'api' (its dismiss()). |
The types are exported too: GuiToastOptions, GuiToastVariant, GuiToastHandle and
GuiDismissReason.
The API of <gui-toaster>:
Properties
| Property | Type | Default | Description |
|---|---|---|---|
placement | GuiToasterPlacement | 'bottom-end' | Where the toasts stack. |
max | number | 3 | How many toasts show at once; the rest wait. |
regionLabel
attribute region-label | string | – | The region's accessible name. Defaults to "Notifications". |
dismissLabel
attribute dismiss-label | string | – | The close buttons' accessible name. Defaults to "Dismiss notification". |
Methods
| Method | Description |
|---|---|
show(id: string, options: GuiToastOptions): void | Shows a toast, or queues it when the toaster is full. A toast with the id of one already here replaces it. toast calls it. |
dismiss(id: string, reason: GuiDismissReason): | Closes a toast, or drops it from the queue, and fires gui-dismiss. |
Events
Every event bubbles and is composed, so you can listen on any ancestor.
| Event | Description |
|---|---|
gui-dismiss | A toast closed. detail.id is its id and detail.reason why it closed. |
gui-action | The user pressed a toast's action. detail.value is the toast's id and detail.item the toast. |
Examples
Section titled “Examples”Variants
Section titled “Variants”variant gives the toast the color of an intent, as on gui-alert, over an opaque background,
since it floats above the page. title adds a heading above the message.
import { GuiButton, GuiToaster } from '@golemui/gui-components/react';import { toast, type GuiToastOptions, type GuiToastVariant,} from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
const toasts: Record<GuiToastVariant, Omit<GuiToastOptions, 'variant'>> = { default: { message: 'Your changes are saved as you type.' }, info: { title: 'New version', message: 'Reload to get the latest features.' }, success: { title: 'Invite sent', message: 'Grace will get an email shortly.' }, warning: { title: 'Almost full', message: 'You have used 90% of your storage.' }, error: { title: 'Could not save', message: 'Check your connection and try again.' },};
const labels: Record<GuiToastVariant, string> = { default: 'Default', info: 'Info', success: 'Success', warning: 'Warning', error: 'Error',};
export function ToastVariants() { return ( <> <div className="gui-grid gui-grid--row gui-grid--justify-start"> {(Object.keys(toasts) as GuiToastVariant[]).map((variant) => ( <div key={variant} className="gui-grid__cell"> <GuiButton id={`toast-${variant}`} label={labels[variant]} variant="outlined" onClick={() => toast({ ...toasts[variant], variant })} /> </div> ))} </div> <GuiToaster /> </> );}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/button';import { toast, type GuiToastOptions, type GuiToastVariant,} from '@golemui/gui-components/toast';
const toasts: Record<GuiToastVariant, Omit<GuiToastOptions, 'variant'>> = { default: { message: 'Your changes are saved as you type.' }, info: { title: 'New version', message: 'Reload to get the latest features.' }, success: { title: 'Invite sent', message: 'Grace will get an email shortly.' }, warning: { title: 'Almost full', message: 'You have used 90% of your storage.' }, error: { title: 'Could not save', message: 'Check your connection and try again.' },};
@Component({ selector: 'app-toast-variants', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <div class="gui-grid gui-grid--row gui-grid--justify-start"> @for (button of buttons; track button.variant) { <div class="gui-grid__cell"> <gui-button [id]="'toast-' + button.variant" [label]="button.label" variant="outlined" (click)="show(button.variant)" ></gui-button> </div> } </div> <gui-toaster></gui-toaster> `,})export class ToastVariantsComponent { buttons: { variant: GuiToastVariant; label: string }[] = [ { variant: 'default', label: 'Default' }, { variant: 'info', label: 'Info' }, { variant: 'success', label: 'Success' }, { variant: 'warning', label: 'Warning' }, { variant: 'error', label: 'Error' }, ];
show(variant: GuiToastVariant) { toast({ ...toasts[variant], variant }); }}<script setup lang="ts">import '@golemui/gui-components/button';import { toast, type GuiToastOptions, type GuiToastVariant,} from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
const toasts: Record<GuiToastVariant, Omit<GuiToastOptions, 'variant'>> = { default: { message: 'Your changes are saved as you type.' }, info: { title: 'New version', message: 'Reload to get the latest features.' }, success: { title: 'Invite sent', message: 'Grace will get an email shortly.' }, warning: { title: 'Almost full', message: 'You have used 90% of your storage.' }, error: { title: 'Could not save', message: 'Check your connection and try again.' },};
const buttons: { variant: GuiToastVariant; label: string }[] = [ { variant: 'default', label: 'Default' }, { variant: 'info', label: 'Info' }, { variant: 'success', label: 'Success' }, { variant: 'warning', label: 'Warning' }, { variant: 'error', label: 'Error' },];</script>
<template> <div class="gui-grid gui-grid--row gui-grid--justify-start"> <div v-for="button in buttons" :key="button.variant" class="gui-grid__cell"> <gui-button :id="`toast-${button.variant}`" :label="button.label" variant="outlined" @click="toast({ ...toasts[button.variant], variant: button.variant })" ></gui-button> </div> </div> <gui-toaster></gui-toaster></template>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/button';import { toast, type GuiToastOptions, type GuiToastVariant,} from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
const toasts: Record<GuiToastVariant, Omit<GuiToastOptions, 'variant'>> = { default: { message: 'Your changes are saved as you type.' }, info: { title: 'New version', message: 'Reload to get the latest features.' }, success: { title: 'Invite sent', message: 'Grace will get an email shortly.' }, warning: { title: 'Almost full', message: 'You have used 90% of your storage.' }, error: { title: 'Could not save', message: 'Check your connection and try again.' },};
const buttons: { variant: GuiToastVariant; label: string }[] = [ { variant: 'default', label: 'Default' }, { variant: 'info', label: 'Info' }, { variant: 'success', label: 'Success' }, { variant: 'warning', label: 'Warning' }, { variant: 'error', label: 'Error' },];
@customElement('toast-variants')export class ToastVariants extends LitElement { protected override createRenderRoot() { return this; }
override render() { return html` <div class="gui-grid gui-grid--row gui-grid--justify-start"> ${buttons.map( ({ variant, label }) => html` <div class="gui-grid__cell"> <gui-button id=${`toast-${variant}`} label=${label} variant="outlined" @click=${() => toast({ ...toasts[variant], variant })} ></gui-button> </div> `, )} </div> <gui-toaster></gui-toaster> `; }}<div class="gui-grid gui-grid--row gui-grid--justify-start"> <div class="gui-grid__cell"> <gui-button id="toast-default" label="Default" variant="outlined"></gui-button> </div> <div class="gui-grid__cell"> <gui-button id="toast-info" label="Info" variant="outlined"></gui-button> </div> <div class="gui-grid__cell"> <gui-button id="toast-success" label="Success" variant="outlined"></gui-button> </div> <div class="gui-grid__cell"> <gui-button id="toast-warning" label="Warning" variant="outlined"></gui-button> </div> <div class="gui-grid__cell"> <gui-button id="toast-error" label="Error" variant="outlined"></gui-button> </div></div><gui-toaster></gui-toaster>
<script type="module"> // In your app: import { toast } from '@golemui/gui-components/toast'; import { toast } from 'https://cdn.jsdelivr.net/npm/@golemui/gui-components@2.1.0/toast/+esm';
const toasts = { default: { message: 'Your changes are saved as you type.' }, info: { title: 'New version', message: 'Reload to get the latest features.' }, success: { title: 'Invite sent', message: 'Grace will get an email shortly.' }, warning: { title: 'Almost full', message: 'You have used 90% of your storage.' }, error: { title: 'Could not save', message: 'Check your connection and try again.' }, };
for (const [variant, options] of Object.entries(toasts)) { document.querySelector(`#toast-${variant}`).addEventListener('click', () => { toast({ ...options, variant }); }); }</script>An action
Section titled “An action”action adds a button to the toast, such as Undo. It runs onAction, then closes the toast. A
toast with an action stays until the user closes it, so the user has time to reach the button.
Keep the action available elsewhere too: a toast goes away, and a screen reader user may hear it
after they moved on.
The card is on the board.
import { useState } from 'react';import { GuiButton, GuiToaster } from '@golemui/gui-components/react';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
export function ToastAction() { const [archived, setArchived] = useState(false);
const archive = () => { setArchived(true); toast({ message: 'Card archived.', action: { label: 'Undo', onAction: () => setArchived(false) }, }); };
return ( <> <GuiButton id="archive-card" label="Archive card" variant="outlined" onClick={archive} /> <p id="card-status" role="status"> {archived ? 'The card is archived.' : 'The card is on the board.'} </p> <GuiToaster /> </> );}import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';
@Component({ selector: 'app-toast-action', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <gui-button id="archive-card" label="Archive card" variant="outlined" (click)="archive()" ></gui-button> <p id="card-status" role="status"> {{ archived() ? 'The card is archived.' : 'The card is on the board.' }} </p> <gui-toaster></gui-toaster> `,})export class ToastActionComponent { archived = signal(false);
archive() { this.archived.set(true); toast({ message: 'Card archived.', action: { label: 'Undo', onAction: () => this.archived.set(false) }, }); }}<script setup lang="ts">import { ref } from 'vue';import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
const archived = ref(false);
function archive() { archived.value = true; toast({ message: 'Card archived.', action: { label: 'Undo', onAction: () => (archived.value = false) }, });}</script>
<template> <gui-button id="archive-card" label="Archive card" variant="outlined" @click="archive" ></gui-button> <p id="card-status" role="status"> {{ archived ? 'The card is archived.' : 'The card is on the board.' }} </p> <gui-toaster></gui-toaster></template>import { LitElement, html } from 'lit';import { customElement, state } from 'lit/decorators.js';import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
@customElement('toast-action')export class ToastAction extends LitElement { @state() private archived = false;
protected override createRenderRoot() { return this; }
private archive() { this.archived = true; toast({ message: 'Card archived.', action: { label: 'Undo', onAction: () => (this.archived = false) }, }); }
override render() { return html` <gui-button id="archive-card" label="Archive card" variant="outlined" @click=${this.archive} ></gui-button> <p id="card-status" role="status"> ${this.archived ? 'The card is archived.' : 'The card is on the board.'} </p> <gui-toaster></gui-toaster> `; }}<gui-button id="archive-card" label="Archive card" variant="outlined"></gui-button><p id="card-status" role="status">The card is on the board.</p><gui-toaster></gui-toaster>
<script type="module"> // In your app: import { toast } from '@golemui/gui-components/toast'; import { toast } from 'https://cdn.jsdelivr.net/npm/@golemui/gui-components@2.1.0/toast/+esm';
const status = document.querySelector('#card-status');
document.querySelector('#archive-card').addEventListener('click', () => { status.textContent = 'The card is archived.'; toast({ message: 'Card archived.', action: { label: 'Undo', onAction: () => { status.textContent = 'The card is on the board.'; }, }, }); });</script>Updating a toast
Section titled “Updating a toast”A toast with the id of one on screen replaces it, with a fresh time on screen. Use it for a
task that ends later, such as an upload: show a toast that stays, then replace it with the
result. The handle’s dismiss() closes a toast from your code.
import { GuiButton, GuiToaster } from '@golemui/gui-components/react';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
function upload() { // One id: the second toast replaces the first one. toast({ id: 'report-upload', message: 'Uploading report.pdf…', duration: Infinity }); // Stands in for the upload. setTimeout(() => { toast({ id: 'report-upload', message: 'report.pdf uploaded.', variant: 'success' }); }, 2000);}
export function ToastUpdate() { return ( <> <GuiButton id="upload-report" label="Upload report" variant="outlined" onClick={upload} /> <GuiToaster /> </> );}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';
@Component({ selector: 'app-toast-update', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <gui-button id="upload-report" label="Upload report" variant="outlined" (click)="upload()" ></gui-button> <gui-toaster></gui-toaster> `,})export class ToastUpdateComponent { upload() { // One id: the second toast replaces the first one. toast({ id: 'report-upload', message: 'Uploading report.pdf…', duration: Infinity }); // Stands in for the upload. setTimeout(() => { toast({ id: 'report-upload', message: 'report.pdf uploaded.', variant: 'success' }); }, 2000); }}<script setup lang="ts">import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
function upload() { // One id: the second toast replaces the first one. toast({ id: 'report-upload', message: 'Uploading report.pdf…', duration: Infinity }); // Stands in for the upload. setTimeout(() => { toast({ id: 'report-upload', message: 'report.pdf uploaded.', variant: 'success' }); }, 2000);}</script>
<template> <gui-button id="upload-report" label="Upload report" variant="outlined" @click="upload" ></gui-button> <gui-toaster></gui-toaster></template>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
@customElement('toast-update')export class ToastUpdate extends LitElement { protected override createRenderRoot() { return this; }
private upload() { // One id: the second toast replaces the first one. toast({ id: 'report-upload', message: 'Uploading report.pdf…', duration: Infinity }); // Stands in for the upload. setTimeout(() => { toast({ id: 'report-upload', message: 'report.pdf uploaded.', variant: 'success' }); }, 2000); }
override render() { return html` <gui-button id="upload-report" label="Upload report" variant="outlined" @click=${this.upload} ></gui-button> <gui-toaster></gui-toaster> `; }}<gui-button id="upload-report" label="Upload report" variant="outlined"></gui-button><gui-toaster></gui-toaster>
<script type="module"> // In your app: import { toast } from '@golemui/gui-components/toast'; import { toast } from 'https://cdn.jsdelivr.net/npm/@golemui/gui-components@2.1.0/toast/+esm';
document.querySelector('#upload-report').addEventListener('click', () => { // One id: the second toast replaces the first one. toast({ id: 'report-upload', message: 'Uploading report.pdf…', duration: Infinity }); // Stands in for the upload. setTimeout(() => { toast({ id: 'report-upload', message: 'report.pdf uploaded.', variant: 'success' }); }, 2000); });</script>Placement and the queue
Section titled “Placement and the queue”placement on the toaster sets where the toasts stack: a corner, top-start, top-end,
bottom-start or bottom-end, the default, or the middle of the top or bottom edge, top or
bottom. The newest toast is next to that edge. max is how many show at once, 3 by default:
the rest wait in a queue, and each one shows when another closes.
A page can have more than one toaster. Give a toaster an id, and pass it to toast() as
toaster.
import { useRef } from 'react';import { GuiButton, GuiToaster } from '@golemui/gui-components/react';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
export function ToastPlacement() { const count = useRef(0);
const notify = () => { count.current += 1; toast({ toaster: 'top-toaster', message: `Notification ${count.current}` }); };
return ( <> <GuiButton id="notify-top" label="Show at the top" variant="outlined" onClick={notify} /> <GuiToaster id="top-toaster" placement="top" max={2} /> </> );}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';
@Component({ selector: 'app-toast-placement', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <gui-button id="notify-top" label="Show at the top" variant="outlined" (click)="notify()" ></gui-button> <gui-toaster id="top-toaster" placement="top" max="2"></gui-toaster> `,})export class ToastPlacementComponent { private count = 0;
notify() { this.count += 1; toast({ toaster: 'top-toaster', message: `Notification ${this.count}` }); }}<script setup lang="ts">import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
let count = 0;
function notify() { count += 1; toast({ toaster: 'top-toaster', message: `Notification ${count}` });}</script>
<template> <gui-button id="notify-top" label="Show at the top" variant="outlined" @click="notify" ></gui-button> <gui-toaster id="top-toaster" placement="top" :max="2"></gui-toaster></template>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/button';import { toast } from '@golemui/gui-components/toast';import '@golemui/gui-components/index.css';
@customElement('toast-placement')export class ToastPlacement extends LitElement { private count = 0;
protected override createRenderRoot() { return this; }
private notify() { this.count += 1; toast({ toaster: 'top-toaster', message: `Notification ${this.count}` }); }
override render() { return html` <gui-button id="notify-top" label="Show at the top" variant="outlined" @click=${this.notify} ></gui-button> <gui-toaster id="top-toaster" placement="top" max="2"></gui-toaster> `; }}<gui-button id="notify-top" label="Show at the top" variant="outlined"></gui-button><gui-toaster id="top-toaster" placement="top" max="2"></gui-toaster>
<script type="module"> // In your app: import { toast } from '@golemui/gui-components/toast'; import { toast } from 'https://cdn.jsdelivr.net/npm/@golemui/gui-components@2.1.0/toast/+esm';
let count = 0;
document.querySelector('#notify-top').addEventListener('click', () => { count += 1; toast({ toaster: 'top-toaster', message: `Notification ${count}` }); });</script>Timing
Section titled “Timing”A toast closes on its own after its duration. Its time pauses while the pointer is over the
toasts, while the focus is in them, and while the browser tab is hidden, so the user doesn’t miss
a toast they are reading or reaching for. The user can close a toast at any time with its close
button, or with Escape while the focus is in it.
In a dialog
Section titled “In a dialog”While a gui-dialog is open, the rest of the page is inert,
and so would be the toasts. The toaster moves its toasts inside the open dialog until it closes,
so the user can still read them and use their buttons. A <dialog> you open with showModal()
yourself, outside a gui-dialog, hides them.
Events
Section titled “Events”<gui-toaster> fires gui-dismiss when a toast closes, with its id and the reason in
event.detail, and gui-action when the user presses a toast’s action, with the toast’s id in
event.detail.value. They suit code that watches every toast, such as analytics: for one toast,
onDismiss and onAction are simpler.
Styling
Section titled “Styling”Anatomy
Section titled “Anatomy”<gui-toaster> renders its toasts in a region it shows in the top layer while it has toasts.
Each toast has a body, the action when it has one, and a close button. Two visually hidden live
regions after the list announce the toasts:
<gui-toaster placement="bottom-end"> <section class="gui-toaster__region" popover="manual" aria-label="Notifications" data-placement="bottom-end" > <ol class="gui-toaster__list"> <li class="gui-toast" data-id="gui-toast-1" data-variant="success"> <div class="gui-toast__body"> <p class="gui-toast__title">Invite sent</p> <p class="gui-toast__message">Grace will get an email shortly.</p> </div> <button type="button" class="gui-toast__action">Undo</button> <button type="button" class="gui-toast__close" aria-label="Dismiss notification" > <svg aria-hidden="true">…</svg> </button> </li> </ol> <div class="gui-visually-hidden" role="status" aria-atomic="false"></div> <div class="gui-visually-hidden" role="alert" aria-atomic="false"></div> </section></gui-toaster>| Class | Part |
|---|---|
gui-toaster__region | The region, fixed to the edge data-placement names. It moves into an open gui-dialog. |
gui-toaster__list | The list of the toasts on screen. |
gui-toast | One toast. data-variant names its intent, and data-leaving is set while it fades out. |
gui-toast__body | The title and the message. |
gui-toast__title | The title, when the toast has one. |
gui-toast__message | The message. |
gui-toast__action | The action button, when the toast has one. |
gui-toast__close | The close button. |
The region can move into a dialog, away from gui-toaster, so select its parts by class, not as
descendants of gui-toaster:
/* Square toasts with a stronger title. */.gui-toast { border-radius: 0;}
.gui-toast__title { font-weight: 700;}Tokens
Section titled “Tokens”The toasts read these design tokens. Set them on :root to change every toast:
| Token | What it styles |
|---|---|
--gui-toast-width | The width of the toasts, 22rem by default, never more than the viewport. |
--gui-bg-default | The background of a default toast. |
--gui-border-default | The border of a default toast. |
--gui-text-default | The text of a default toast. |
--gui-intent-*-surface | The background of a toast of that intent: info, success, warning or error. |
--gui-intent-* | The border of a toast of that intent. |
--gui-intent-*-text | The text of a toast of that intent. |
--gui-radius-md | The corner radius of a toast. |
--gui-radius-sm | The corner radius of the buttons. |
--gui-shadow-lg | The shadow of a toast. |
--gui-shadow-focus | The focus ring of the buttons. |
--gui-font-family | The font. |
--gui-font-sm | The text size. |
--gui-space-2 | The space between the toasts, and the padding of the action. |
--gui-space-3 | The padding of a toast, and the space between its parts. |
--gui-space-4 | The space from the edge of the viewport, and the slide of a new toast. |
--gui-overlay-duration | How long a toast takes to fade and slide in, and to fade out. Reduced motion skips it. |
To restyle beyond the tokens, see Overriding styles; for dark mode and the Clay theme, see Themes and dark mode.
Accessibility
Section titled “Accessibility”- Announcements. Screen readers read each toast when it shows: its title, then its message.
A toast of any variant but
errorwaits until the user is idle, through astatuslive region. Anerrorinterrupts, through analertregion. - Region. The toasts are in a region named “Notifications”, which users can reach from a
screen reader’s list of landmarks. Rename it with
region-label, or translate it under the keynotifications. - Close button. Each toast has a close button named “Dismiss notification”. Rename it with
dismiss-label, or translate it under the keydismissNotification. - Focus. A toast never takes the focus. When a toast closes while the focus is in it, the focus moves to the next toast, or back to where it was before it entered the toasts.
- Time. A toast’s time pauses while the user points at it or is in it, and a toast with an action or an error stays until the user closes it. Don’t use a toast for something the user must answer: use a dialog.
| Key | Action |
|---|---|
| Tab | Moves through the buttons of the toasts. |
| Enter Space | Presses the action or the close button. |
| Escape | In a toast: closes it. |
What every element shares, such as translating the messages, is in Accessibility.