Toast
Short messages that stack in a corner, burn a thin fuse for the time they have left, spread out under the pointer and swipe away.
- enhancer
- notification
- message
- swipe
- timer
- alert
- since 0.2
Background Studio: tune it below, then copy the code
Your system asks for reduced motion: the demo shows its final state and nothing moves.
Live demo
Toast example
Code
It follows the controls above: change an option and the code changes with it.
<link rel="stylesheet" href="/axi0/motion/motion.css?v=6">
<script src="/axi0/motion/motion.js?v=10" defer></script>
<div class="demo-row">
<button type="button" class="demo-btn" data-motion="toast" data-motion-inline="true" data-motion-show="true" data-motion-tone="success" data-motion-title="Draft saved" data-motion-text="A copy stays on this device too.">Save draft</button>
<button type="button" class="demo-btn" data-motion="toast" data-motion-inline="true" data-motion-text="Invite sent to Sam" data-motion-action="Undo">Send invite</button>
<button type="button" class="demo-btn" data-motion="toast" data-motion-inline="true" data-motion-tone="error" data-motion-title="Upload failed" data-motion-text="The file is over 25 MB.">Upload</button>
</div>
import { Toast } from "./motion/react/Toast";
<Toast>Your content</Toast>
<script setup lang="ts">
import Toast from "./motion/vue/Toast.vue";
</script>
<template>
<Toast>Your content</Toast>
</template>
const el = document.querySelector("#title");
el.dataset.motion = "toast";
The wrappers: Toast.tsx (React, TypeScript) and Toast.vue (Vue). Both render the same attributes as the HTML; the loader does the rest.
Options
| Attribute | Default | What it does |
|---|---|---|
data-motion-text | Saved | the message |
data-motion-title | auto | a bold first line (optional) |
data-motion-tone | info | the icon and color; error toasts are read at once |
data-motion-action | auto | a button inside the toast, such as Undo (it fires a toast-action event on the trigger) |
data-motion-duration | 6000 | how long it stays; 0 keeps it until it is closed |
data-motion-inline | false | stack the toasts at the bottom of the trigger's parent instead of the page |
data-motion-show | false | raise one toast as soon as the trigger comes into view |
Accessibility
- Toasts live in a labeled region ("Notifications") whose list is a polite live region, so each new message is read once; error toasts use role="alert" and are read at once. - Every toast has a Dismiss button; Escape closes the focused toast and focus moves to the next one (or back to where it was). Alt+T jumps to the newest toast on the page. - The time left stops running while the pointer rests on the stack, while focus is inside it and while the tab is hidden, so nobody loses a message they are reading. Use duration="0" for messages that must stay. - Swiping down closes a toast on touch screens; every swipe has a button that does the same. - Reduced motion hides the fuse and shows and hides toasts with no movement; the timer still runs. Reduced motion shows every state at once, with no movement, and stops anything that would move on its own. Frame loops and CSS animations pause off screen and in hidden tabs. Only transform, opacity and paint animate, so nothing around it moves.
Size
toast.js is 3.0 KB gzip, with components-kit.js 3.9 KB it needs. A page loads the loader (2.7 KB) and core.js (1.4 KB) once, whatever it uses.