Word by Word
Les mots surgissent l'un après l'autre avec un fondu et une montée douce — révélation dramatique construite sur une seule animation CSS et du JS vanilla.
Vous aurez accès à la démo interactive avec un compte gratuit.
Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Texte comprend 56 effets, dont 4 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
L'effet repose sur une animation CSS unique, wordAppear, qui fait passer chaque mot de opacity:0; transform:translateY(20px) à son état final en 0,6 s avec une courbe ease et un fill-mode:forwards. Chaque mot est placé dans un <span> avec un animation-delay inline calculé par la fonction JS splitWords : le premier mot à 0 s, puis +0,3 s par mot supplémentaire.
La fonction splitWords(el, text, delay) découpe la chaîne par espaces, vide le conteneur cible, crée un <span> par mot avec son animation-delay calculé (i * delay + 's'), et insère les nœuds dans le DOM. Dès leur insertion, la règle CSS .text-word-by-word span prend le relais et lance les animations en cascade — aucun JS supplémentaire requis pour le rendu initial.
Le bouton Replay vide l'élément (innerHTML = ''), attend 50 ms pour que le navigateur purge les styles calculés et réinitialise le cycle d'animation, puis rappelle initWordByWord(). Ce délai est nécessaire : supprimer et réinsérer immédiatement les spans sans pause empêche le navigateur de redémarrer le @keyframes.
Note de code : dans la version d'origine, replayWordByWord et splitWords sont définies à l'intérieur de l'IIFE et non exposées globalement — le bouton onclick ne fonctionnera pas sans adaptation (voir FAQ). L'animation initiale, elle, fonctionne en pur CSS dès que les <span> sont dans le DOM.
Accessibilité
- prefers-reduced-motion absent : l'effet ne vérifie pas la préférence système — tous les mots s'animent même si l'utilisateur préfère réduire le mouvement. Pour couvrir ce cas, ajoutez :
@media (prefers-reduced-motion: reduce) { .text-word-by-word span { animation: none; opacity: 1; transform: none; } }. - Le texte de chaque mot est dans le DOM en clair : les lecteurs d'écran lisent la phrase complète sans attendre la fin de l'animation.
- Le bouton Replay est un élément
<button>natif, focusable au clavier (Tab · Entrée · Espace) sans configuration supplémentaire. - Texte blanc sur fond sombre (#0a0a0f) : ratio de contraste supérieur à 10:1 — conforme WCAG AA et AAA.
- Aucun attribut
aria-*nirolesur le conteneur : ajouteraria-labelsi le texte animé est le seul contenu accessible de la section.
Compatibilité navigateur
Nécessite CSS3 @keyframes et animation-fill-mode — disponibles dans tous les navigateurs modernes depuis 2013. Zéro dépendance externe, aucun canvas requis.
Si les animations CSS sont désactivées (mode haut contraste sous Windows, navigateur ancien), tous les spans s'affichent à <code>opacity:0</code> par défaut — le texte disparaît. Pour garantir la lisibilité sans animation, ajoutez <code>@media (prefers-reduced-motion: reduce) { .text-word-by-word span { opacity: 1; transform: none; animation: none; } }</code>.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="demo-preview">
<span class="demo-text text-word-by-word" id="wordByWordText">
<span style="animation-delay: 0s">WORD</span>
<span style="animation-delay: 0.3s">BY</span>
<span style="animation-delay: 0.6s">WORD</span>
</span>
<button class="replay-btn" onclick="replayWordByWord()">Replay</button>
</div>
HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| delay (arg. splitWords) | 0.3 | Secondes entre l'apparition de deux mots consécutifs. 0,5 s = rythme dramatique ; 0,1 s = cascade rapide. |
| animation-duration (.text-word-by-word span) | 0.6s | Durée de l'entrée de chaque mot. 0,9 s = fondu très doux ; 0,25 s = claquement sec. |
| translateY initial (.text-word-by-word span) | 20px | Hauteur de départ avant la montée. 0 px = fondu pur sans translation ; 40 px = entrée spectaculaire depuis le bas. |
| animation-timing-function | ease | Courbe de l'animation. ease-out pour une décélération naturelle ; cubic-bezier(0.22,1,0.36,1) pour un overshoot élastique. |
| font-size (.demo-text) | 2.5rem | Taille du texte. 4–6 rem pour un hero plein écran ; 1,5 rem pour un sous-titre. |
| font-weight (.demo-text) | 800 | Graisse. 700 = bold standard ; 900 = black pour une typographie très affirmée. |
| letter-spacing (.demo-text) | -0.02em | Espacement des lettres. Valeur positive (0,1 em) pour un style all-caps espacé ; plus négative (−0,05 em) pour un titre très serré. |
FAQ
'WORD BY WORD' passée à splitWords() dans initWordByWord() : la fonction découpe automatiquement en mots et calcule les animation-delay. Vous pouvez aussi modifier les <span> directement dans le HTML en ajustant les délais par incréments de 0,3 s.replayWordByWord est définie à l'intérieur de l'IIFE et n'est pas accessible globalement. Exposez-la avant de fermer l'IIFE : window.replayWordByWord = replayWordByWord;. Veillez également à définir splitWords dans la portée globale ou dans l'IIFE avant qu'elle soit appelée.id distinct à chaque .text-word-by-word et appelez splitWords(el, texte, delay) sur chacun. Chaque instance est autonome — elle ne touche que son propre élément et ses propres <span>.