Toast Cascade
Une pile de notifications qui se range seule : chaque message entre par le bas avec un léger rebond (0,4 s), la pile n'en garde que trois — le quatrième pousse le plus ancien dehors par la droite (0,3 s) — et chacun repart de lui-même après 4 s. CSS et 2,5 Ko de JavaScript, fondu de 150 ms si l'utilisateur réduit les animations.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Transitions comprend 52 effets, dont 9 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Le bloc .tc-root déclare son fond (#0a0a0f, texte blanc) et centre en colonne la pile puis le bouton. La pile .tc-stack mesure 180 px de haut, coupe ce qui dépasse (overflow: hidden) et range ses enfants en flex-direction: column-reverse : le premier enfant du DOM est en bas, chaque nouvelle notification se pose au-dessus des autres. Une notification .tc-item fait 220 à 280 px de large, coins de 10 px, dégradé #1e1e2e → #2d2b55 ; à gauche, une pastille de 24 px dont la couleur dit le type : .tc-icon--success vert #10b981, --error rouge #ef4444, --info bleu #3b82f6.
L'entrée est l'animation tcEnter : 0,4 s, de translateY(30px) scale(.9) et opacité 0 jusqu'à la place, sur cubic-bezier(.34, 1.56, .64, 1) — la courbe dépasse 1, d'où le petit rebond en fin de course. Mesuré 60 ms après le clic : échelle 0,955, 13 px sous la place, opacité 0,55 dans Chromium 151 (mêmes ordres dans Firefox 153 et WebKit 26). La sortie ajoute .tc-exit, qui joue tcExit en 0,3 s : 100 px vers la droite, échelle 0,8, opacité 0, tandis que max-height et padding se replient à zéro ; le script retire le nœud à 300 ms. Les notifications restantes glissent alors de 44 px vers le bas d'un mouvement continu, puis des 10 px restants d'un coup quand le script retire le nœud : l'écart de 8 px entre deux notifications et la bordure de 2 px tiennent jusque-là (mesuré image par image dans Chromium et Firefox).
Le script parcourt chaque .tc-root de la page : plusieurs piles cohabitent, chacune avec son compteur, et le préfixe tc- les distingue des autres notifications de la bibliothèque. addToast() compte les notifications qui ne sortent pas déjà ; à partir de trois, il fait sortir la plus ancienne (la première du DOM, en bas), puis crée la suivante et lui donne une minuterie de 4 000 ms. Les types tournent dans l'ordre succès, erreur, info, avec un message tiré au hasard dans la langue du bloc : data-lang s'il est posé, sinon le lang de la page, français par défaut. Deux réglages de la notification tiennent la pile tranquille quand elle déborde pendant une sortie : max-height: 80px (depuis none, la hauteur maximale ne s'interpole pas) et flex-shrink: 0 (sans lui, le passage à overflow: hidden au milieu de la sortie laisse le flex écraser la notification d'un coup). Au chargement, deux notifications de démonstration arrivent à 300 et 700 ms : retirez les deux setTimeout de la fin du script pour une pile vide au départ.
Accessibilité
- Annonce : la pile porte
aria-live="polite"; un lecteur d'écran lit chaque message à son arrivée, sans couper ce qu'il était en train de dire. La pastille estaria-hidden: le type doit donc se lire dans le texte (« Erreur : … ») si la couleur porte une information. Pour une alerte qui demande une action immédiate, ajoutez une régionrole="alert"à part. - Temps de lecture : chaque notification repart seule après 4 s et le code ne met pas la minuterie en pause au survol. C'est court pour une lecture lente ou une loupe d'écran : n'y mettez rien qu'on ne retrouve pas ailleurs (historique, page de suivi), ou allongez le délai.
- Mouvement réduit : sous
prefers-reduced-motion, l'entrée et la sortie deviennent des fondus de 150 ms (tcFadeIn,tcFadeOut), sans glissement ni rebond — mesuré dans Chromium : animation de 0,15 s, aucune transformation. - Contraste : texte blanc sur le dégradé, 16,4:1 sur
#1e1e2eet 13,2:1 sur#2d2b55. Les signes blancs des pastilles sont plus faibles (2,5:1 sur le vert, 3,8:1 sur le rouge) : ils doublent le texte sans le remplacer. Le bouton indigo#6366f1donne 4,47:1, juste sous le seuil AA de 4,5:1 :#4f46e5l'atteint largement (6,29:1).
Compatibilité navigateur
Animations CSS, flexbox en column-reverse et une cinquantaine de lignes de JavaScript, aucune dépendance. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : même entrée avec rebond, même sortie à droite, trois notifications au plus, pile vide 5 s après le dernier ajout, fondu de 150 ms sous mouvement réduit. Le script s'appuie sur NodeList.forEach et Element.closest, présents depuis Chrome 51, Firefox 50 et Safari 10.
Sans JavaScript, la pile reste vide et le bouton ne fait rien : affichez les messages importants dans la page elle-même. Avec le mouvement réduit, les notifications apparaissent et disparaissent en fondu de 150 ms, au même rythme.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec Premium) :
<div class="tc-root">
<div class="tc-stack" aria-live="polite">
<!-- notifications créées par le script : -->
<div class="tc-item">
<span class="tc-icon tc-icon--success" aria-hidden="true">✓</span><span>…</span>
</div>
</div>
<button class="tc-btn" type="button">Ajouter une notification</button>
</div>
Le code complet HTML + CSS + JS de Toast Cascade, prêt à coller — et les 840 effets. Ou 299 € TTC une fois, accès à vie.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Nombre maximum (JS — toasts.length >= 3) |
3 notifications | Au-delà, la plus ancienne sort quand une nouvelle arrive. Avec 4 ou 5, portez la hauteur de .tc-stack à 230 ou 290 px : une notification sur une ligne mesure 46 px, plus 8 px d'écart. |
Durée d'affichage (JS — 4000) |
4 s | Délai avant le départ automatique de chaque notification. 6 000 à 8 000 ms laissent le temps de lire une phrase entière ; pour une alerte qui doit rester, supprimez la minuterie et ajoutez un bouton de fermeture. |
Entrée (CSS — tcEnter, cubic-bezier(.34, 1.56, .64, 1)) |
0,4 s, 30 px de montée, rebond | ease-out à la place de la courbe supprime le rebond ; translateY(60px) dans la première étape donne une montée plus longue. |
Sortie (CSS — tcExit, translateX(100px)) |
0,3 s vers la droite | translateX(-100px) fait sortir à gauche. Si vous allongez l'animation, alignez le 300 du setTimeout de removeToast, sinon le nœud disparaît avant la fin. |
Hauteur de la pile (CSS — .tc-stack height) |
180px | Trois notifications d'une ligne y tiennent (174 px avec la marge intérieure). Pour une pile collée au bas de l'écran, mettez .tc-root en position: fixed; right: 16px; bottom: 16px; width: 320px. |
Messages et types (JS — objet TYPES) |
3 types × 3 messages, en français et en anglais | Remplacez les textes, ajoutez une langue (de: […]) ou un type ; pour un nouveau type, ajoutez aussi sa couleur .tc-icon--warning { background: #f59e0b; }. |
Couleurs (CSS — .tc-item, .tc-icon--*) |
dégradé #1e1e2e → #2d2b55 |
Sur une page claire : background: #fff; color: #111; border-color: #e5e7eb et une ombre plus légère ; gardez au moins 4,5:1 entre le texte et le fond. |
FAQ
flex-direction: column-reverse : le premier enfant du DOM, le plus ancien, est en bas, et c'est lui qui sort quand la pile est pleine. Pour l'ordre inverse (la plus récente en bas, contre le bord de l'écran), passez .tc-stack en flex-direction: column; justify-content: flex-end : la plus ancienne reste la première du DOM, donc en haut, et le script la fait toujours sortir en premier.showToast(type, message). Toast Cascade vit dans son propre bloc (pas de position: fixed), n'en garde que trois en poussant le plus ancien dehors, entre avec un rebond et repart à 4 s ; rien n'est exposé sur window. Choisissez Toast Stack pour des retours d'action à l'échelle de la page, Toast Cascade pour un flux d'événements dans une zone d'écran (supervision, direct, écran de salle).addToast(), qui choisit un type et un message dans TYPES. Pour pousser un message venu de votre application, donnez-lui deux paramètres — function addToast(type, text), puis utilisez type et text à la place du tirage — et rendez-la accessible depuis le bloc, par exemple root.addToast = addToast; juste après sa définition : document.querySelector('.tc-root').addToast('error', 'Porte quai 3 ouverte'). Le texte est posé avec textContent : un message saisi par un utilisateur s'affiche tel quel, sans être interprété comme du HTML.