Every app has them now — those little notifications that slide in, stack, and fade. Sonner, react-hot-toast, your bank's web app. The whole system is ~40 lines: a list in state, a fixed container, and a timer per toast.
🔔 Try it live: https://dev48v.infy.uk/design/day11-toasts.html
1. Toasts are just a list of state
let toasts = []; // [{ id, type, message }]
function toast(msg, type) { toasts.push({ id: uid(), msg, type }); render(); }
Decoupling the data (the list) from the display lets you fire a toast from anywhere — a button, a fetch handler, an error boundary.
2. One fixed "portal" container
<div class="fixed bottom-5 right-5 flex flex-col gap-2"></div>
fixed floats it above everything no matter which component called toast().
3. Auto-dismiss with a timer (+ pause on hover)
setTimeout(() => dismiss(id), 4000);
container.onmouseenter = () => paused = true;
The pro touch: pause every timer while the user hovers, so notifications don't vanish mid-read.
4. Variants from a lookup
success/error/info/loading differ only by an icon and a colour — a small type → style map keeps the component generic.
5. Animate in AND out
The forgotten half is the EXIT: add an exit class, listen for animationend, then remove. Smooth on both ends is what separates polished from janky.
The takeaway
List in state + fixed portal + timers + variants + enter/exit animation. Fire some toasts.
Top comments (0)