Navigation✨ Premium

Toast Stack

Three toast types (success, error, info) stack with 300 ms gaps and auto-dismiss after 3 seconds — sequence driven by plain setTimeouts.

JSStackQueue

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Navigation has 36 effects, including 4 free. Explore the category →

3 usage examples

DevOps dashboard — Cascading deployment alerts — Toast Stack example 1

① DevOps dashboard — Cascading deployment alerts

WhenThe operator triggers a deployment from the dashboard; the pipeline fires several successive events (build succeeded, cache cleared, network error).
WhyThree toast types appear in sequence and document each step without interrupting the workflow — the operator reads the full status at a glance without leaving their current view.
Settings3 toasts 300 ms apart: success 'Build complete', info 'Cache cleared', error 'CDN timeout #3'.
CSV import tool — Batch processing results — Toast Stack example 2

② CSV import tool — Batch processing results

WhenThe user submits a data file; the back-end responds with several simultaneous results (rows processed, duplicates skipped, report generated).
WhyThree toasts summarise a complex operation without redirecting to a new page or forcing a scroll to a status banner.
Settingssuccess '382 rows imported', info '14 duplicates skipped', success 'Excel report ready' — 300 ms gap between each.
Checkout tunnel — Three-step order confirmation — Toast Stack example 3

③ Checkout tunnel — Three-step order confirmation

WhenThe buyer confirms their cart; the system sequentially validates the address, payment, and delivery date.
WhySpacing confirmations 300 ms apart creates a sense of progress: the user perceives real processing rather than a monolithic success page.
Settingsinfo 'Address verified', success 'Payment confirmed', success 'Delivery scheduled D+2' — auto-dismiss at 3 s.

How it works

showToast(type, message) creates a <div class="toast {type}"> with an inline SVG icon (checkmark for success, cross for error, info-circle for info) and the message as plain text, then appends it to #toastContainer via appendChild. A first setTimeout at 3,000 ms adds the hiding class, triggering the CSS exit transition; a second setTimeout at 300 ms removes the element from the DOM.

showMultipleToasts() chains three showToast calls with delays of 0, 300, and 600 ms. Stacking emerges naturally from the flex-column container: each toast inserts at the bottom without positional math — the container height auto-adjusts and existing toasts remain in place.

The enter animation is CSS-driven: a keyframe slides the toast in from the right (translateX(100% + gap), opacity 0 → 1) in ~300 ms. Exit reverses this when hiding is applied. The 300 ms window between adding hiding and removing the DOM node lets the transition complete before the reflow.

The JS uses no external library: only document.createElement, appendChild, classList, and setTimeout. All icons are fully inline SVG — no sprite import, no icon font.

Accessibility

  • prefers-reduced-motion: absent from the code — the slide animation always runs, including for users who enabled the OS preference. Fix by adding @media (prefers-reduced-motion: reduce) { .toast { animation: none; } }.
  • #toastContainer has no aria-live or role="status" declaration: screen readers (NVDA, VoiceOver) do not announce toasts automatically. Add aria-live="polite" or aria-live="assertive" depending on message urgency.
  • SVG icons have no aria-label or <title>, and no aria-hidden="true" — they are passed to assistive technologies as unnamed graphics.
  • The trigger button (.toast-trigger) is a native <button>, keyboard-accessible and focusable without extra JavaScript.
  • Toast background contrast must be verified in your integration context: the #1a1a2e background on a dark site may reduce readability if the container is not fully opaque.

Browser compatibility

Relies only on standard DOM APIs (createElement, classList, setTimeout) and CSS transitions — no polyfill required.

Chrome 90+✓ Full
Firefox 88+✓ Full
Safari 14+✓ Full
Edge 90+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

Without JS the button is inactive and no toasts appear — the page stays functional. If <code>#toastContainer</code> is missing from the DOM, <code>showToast()</code> returns silently (<code>if (!s) return</code>) with no JS error.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="toast-container" id="toastContainer"></div>

<div class="component-demo">
  <button class="toast-trigger stack" onclick="showMultipleToasts()">
    Show Toast Stack
  </button>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
setTimeout 3000 3,000 ms Display duration before auto-dismiss. Change 3e3 (first setTimeout in showToast) to your target value in milliseconds.
Delays 300 / 600 ms 300 ms / 600 ms Gap between toasts 2 and 3 in showMultipleToasts(). Lower to 150/300 for a quick burst, raise to 600/1200 for a narrative rhythm.
CSS .toast.success border-left #10b981 Emerald color of the left border and icon for success toasts. Swap for your brand color.
CSS .toast.error border-left #ef4444 Red color of the left border and icon for error toasts.
CSS .toast.info border-left #6366f1 Indigo color of the left border and icon for info toasts.
showToast(type, msg) Call directly to add a single toast. type accepts 'success', 'error', or 'info' — the string becomes the CSS class of the toast.
Inline SVG icons inside showToast() Edit the SVG blocks in showToast() per conditional branch to match your design system (Heroicons, Lucide, Phosphor...).

FAQ

Yes — showToast() looks for it with getElementById('toastContainer') and returns silently if absent (if (!s) return). Add <div id="toastContainer" class="toast-container"></div> anywhere in the <body>, ideally just before </body>.
Yes — call showToast(type, message) directly instead of showMultipleToasts(). For a strict singleton (one visible toast at a time), clear the container before each call: document.getElementById('toastContainer').innerHTML = '', or manage a lock variable on the caller side.
Wire showToast() inside .then() / .catch() callbacks. Example: fetch('/api/save').then(r => r.ok ? showToast('success','Saved!') : showToast('error','Failed')).catch(() => showToast('error','Network error')). For multi-step sequences, chain several .then() with nested setTimeouts to maintain the visual timing.