Bounce In Letters
Chaque lettre surgit du haut avec un rebond élastique — animation CSS pure en cascade à 80 ms d'intervalle, zéro dépendance, pour des titres mémorables.
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'animation repose sur un @keyframes CSS unique — bounceInLetter — qui fait passer chaque lettre de opacity:0, translateY(-50px) scale(.5) à opacity:1, translateY(0) scale(1) en 600 ms. L'easing cubic-bezier(.68, -.55, .265, 1.55) produit un dépassement élastique : le 4ᵉ paramètre dépasse 1, ce qui pousse la lettre légèrement au-delà de sa position finale avant qu'elle ne se stabilise — le rebond caractéristique.
La fonction utilitaire splitText(el, text, delayStep) décompose le texte caractère par caractère et injecte un <span style="animation-delay:Xs"> par lettre. Le délai croît de delayStep à chaque lettre (0 s, 0,08 s, 0,16 s…) — c'est ce qui produit l'entrée en cascade plutôt qu'une entrée simultanée. Le mode animation-fill-mode: forwards assure que chaque lettre reste visible après la fin de son animation, même si les suivantes sont encore en vol.
Le bouton Replay appelle replayBounceIn() : il vide le innerHTML du conteneur puis rappelle splitText après 50 ms — ce délai laisse au navigateur le temps de forcer un recalcul de style avant de réinjecter les spans, ce qui garantit un restart propre de l'animation CSS.
Point de vigilance : en l'état le CSS ne contient pas de règle @media (prefers-reduced-motion). Comme les spans démarrent à opacity:0, si les animations CSS sont désactivées (préférence OS ou très vieux navigateur) le texte reste invisible — pensez à ajouter le repli décrit dans la section A11y.
Accessibilité
- prefers-reduced-motion absent du code : aucune règle @media n'est incluse. Ajoutez
@media (prefers-reduced-motion: reduce) { .text-bounce-in span { animation: none; opacity: 1; transform: none; } }pour les utilisateurs sensibles aux animations. - Le texte est structuré en
<span>inline — les lecteurs d'écran lisent le mot complet dans l'ordre du DOM, sans être perturbés par le découpage lettre par lettre. - Le bouton Replay est un
<button>natif, focusable au clavier et atteignable par Tab — aucun rôle ARIA supplémentaire nécessaire. - Contraste du texte : blanc (
#ffffff) sur fond sombre (#0a0a0f), ratio > 15:1 — largement au-delà de WCAG AA (4,5:1) et AAA (7:1). - En l'absence de support CSS animation (très anciens navigateurs), les spans restent à
opacity:0et le texte est invisible. Repli recommandé :@supports not (animation-name: a) { .text-bounce-in span { opacity:1; transform:none; } }.
Compatibilité navigateur
Repose sur CSS animations, cubic-bezier et animation-fill-mode — supportés dans tous les navigateurs modernes depuis 2015. Zéro dépendance externe.
Sans support CSS animation, les lettres restent à <code>opacity:0</code> (texte invisible). Repli sûr : <code>@supports not (animation-name: a) { .text-bounce-in span { opacity:1; transform: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-bounce-in" id="bounceInText">
<!-- spans générés par splitText(el, 'MOT', 0.08) -->
<span style="animation-delay: 0s">M</span>
<span style="animation-delay: 0.08s">O</span>
<span style="animation-delay: 0.16s">T</span>
</span>
<button class="replay-btn" onclick="replayBounceIn()">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 |
|---|---|---|
| 0.08 (3ᵉ arg de splitText) | 0.08 s | Délai entre chaque lettre. Réduisez à 0,05 s pour un mot court et vif, montez à 0,12 s pour un long mot afin de garder la cascade visible. |
| animation: .6s … | 0.6 s | Durée de l'animation par lettre (CSS, ligne .text-bounce-in span). Augmentez à 0,9 s pour un effet plus lent et cinématique. |
| cubic-bezier(.68, -.55, .265, 1.55) | 1.55 (4ᵉ param.) | Amplitude du rebond élastique. Montez à 1.8 pour un rebond prononcé, descendez à 1.1 pour une entrée plus douce. |
| translateY(-50px) | -50px | Distance de chute initiale en CSS. -80px pour une entrée plus dramatique depuis le haut, -20px pour un glissement subtil. |
| scale(.5) | 0.5 | Échelle de départ de chaque lettre en CSS. 0.8 pour un léger zoom, 0.1 pour une apparition depuis presque zéro. |
| font-size: 2.5rem | 2.5rem | Taille du texte en CSS (classe .demo-text). L'effet fonctionne de 1rem à 8rem — adaptez librement selon le contexte. |
| 'BOUNCE' (2ᵉ arg de splitText) | "BOUNCE" | Texte à animer. Modifiez la chaîne dans l'appel JS pour l'adapter à votre contenu — l'effet fonctionne avec n'importe quelle chaîne Unicode. |
FAQ
splitText(el, texte, delay) prend un élément en premier paramètre — appelez-la sur autant d'éléments que nécessaire avec des id différents. Chaque conteneur doit porter la classe text-bounce-in pour hériter de la règle CSS d'animation.IntersectionObserver : observez le conteneur, et dans le callback appelez splitText(el, texte, delay) dès que isIntersecting devient vrai. Appelez observer.unobserve(el) ensuite pour ne déclencher qu'une seule fois.<span> avec leurs animation-delay individuels. Sans JS, vous pouvez pré-rendre les spans côté serveur ou directement dans le HTML source — c'est d'ailleurs la structure fournie dans l'exemple, qui s'anime dès le chargement sans aucun appel JS supplémentaire.