Elastic Bounce Letters
Chaque lettre bondit depuis une position écrasée grâce à une animation CSS à ressort amorti — stagger configurable lettre par lettre, relance au clic, zéro dépendance.
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
Le cœur de l'effet est @keyframes ktElastic : à 0 % la lettre est aplatie (scaleY(0)) et élargie (scaleX(1.8)) — comme un ressort comprimé. À 40 % elle s'étire vers le haut au-delà de sa taille finale (scaleY(1.3)) en se pinçant latéralement (scaleX(.7)). Deux paliers supplémentaires à 60 % et 80 % simulent les oscillations amorties d'un vrai ressort avant le retour à l'échelle 1×1.
La courbe d'accélération cubic-bezier(.34, 1.56, .64, 1) amplifie l'overshoot : le troisième point de contrôle à 1.56 fait dépasser la valeur cible, reproduisant la physique d'un ressort sans JavaScript. La durée totale est de 0,8 s avec fill-mode: forwards pour maintenir l'état final.
Chaque lettre est un <span class="char"> avec display:inline-block (obligatoire pour que les transformations 2D soient applicables à un nœud inline). La propriété CSS --delay est posée en style inline sur chaque span (0 s, 0,06 s, 0,12 s…) et référencée via animation-delay: var(--delay) : un seul passage d'animation, décalé lettre par lettre.
La classe .active sur le conteneur .kt-elastic déclenche l'animation en cascade. Pour relancer, il suffit de la retirer, de forcer un reflow (el.offsetWidth), puis de la remettre. L'utilitaire JS splitChars(el) redécoupe dynamiquement le texte d'un nœud en <span class="char"> avec les --delay correctement espacés.
Accessibilité
- prefers-reduced-motion absent : aucune règle
@media (prefers-reduced-motion)n'est présente dans le code fourni. Les utilisateurs sensibles aux mouvements verront l'animation complète. Ajoutez@media (prefers-reduced-motion:reduce) { .kt-elastic .char { animation: none; opacity:1; transform:none; } }pour les protéger. - Le contenu textuel est du texte réel dans des
<span>— lisible nativement par tous les lecteurs d'écran, sansaria-hiddenni image de remplacement nécessaire. - Aucun
role,aria-labelouaria-liven'est posé sur le conteneur : le texte étant du contenu statique (pas une notification), cette absence est acceptable ; unaria-labeln'est utile que si le conteneur est présenté comme widget interactif. - Contraste des lettres : couleur
#fffsur fond#0a0a0f— ratio ≈ 18,1:1, largement supérieur aux seuils WCAG AA (4,5:1) et AAA (7:1). - La relance au clic repose sur
style="cursor:pointer"sans<button>nitabindex: l'élément n'est pas focusable au clavier. Enveloppez le conteneur dans un<button>ou ajouteztabindex="0"+ gestionnairekeydownpour une accessibilité clavier complète.
Compatibilité navigateur
Nécessite CSS Transforms (niveau 1) et CSS Custom Properties — supportés dans tous les navigateurs modernes depuis 2017.
Sans CSS Animations, les lettres restent invisibles (<code>opacity:0</code>) car l'état initial est posé en style inline. Ajoutez <code>.no-js .kt-elastic .char { opacity:1; transform:none; }</code> ou retirez les styles inline côté serveur pour les navigateurs anciens.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="kt-text kt-elastic" id="elastic1" data-text="TITRE" style="cursor:pointer;">
<!-- splitChars() génère un <span class="char"> par caractère avec --delay progressif -->
<!-- Exemple pour « TITRE » (5 lettres, stagger 0,06 s) : -->
<span class="char" style="--delay:0s;">T</span>
<span class="char" style="--delay:0.06s;">I</span>
<span class="char" style="--delay:0.12s;">T</span>
<span class="char" style="--delay:0.18s;">R</span>
<span class="char" style="--delay:0.24s;">E</span>
<!-- Ajoutez la classe .active sur le div pour lancer l'animation -->
</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 (inline sur chaque .char) | 0 s, 0,06 s, 0,12 s… | Délai de stagger lettre par lettre. Augmentez à 0,10 s pour un effet plus lent et dramatique ; descendez à 0,03 s pour une entrée quasi-simultanée. |
| animation-duration (.kt-elastic.active .char) | .8s | Durée du rebond par lettre. 0,5 s = nerveux, 1,2 s = cinématique et doux. |
| animation-timing-function (.kt-elastic.active .char) | cubic-bezier(.34, 1.56, .64, 1) | Courbe du ressort. Augmentez le 3ᵉ coefficient (1.56) pour un overshoot plus prononcé ; descendez-le vers 1.0 pour supprimer le dépassement. |
| font-size (.kt-text) | 2.2rem | Taille d'affichage. L'effet est plus impressionnant à grande taille (4–6 rem) où l'écrasement/rebond est bien visible. |
| font-weight (.kt-text) | 800 | Graisse. 900 amplifie l'impact visuel du rebond ; 400 donne un style magazine plus fin. |
| color (.kt-text) | #fff | Couleur des lettres. Changez-la librement — le contraste doit rester ≥ 4,5:1 sur le fond utilisé. |
| splitChars(el) | — | Utilitaire JS exposé globalement : redécoupe dynamiquement le texte d'un nœud .kt-elastic en <span class="char"> avec les --delay progressifs. Appelez-le avant d'ajouter .active si le texte est injecté côté serveur sans pré-découpe. |
FAQ
.active du conteneur, forcez un reflow avec el.offsetWidth (lecture de propriété suffisante), puis rajoutez .active. Exemple : el.classList.remove('active'); void el.offsetWidth; el.classList.add('active');splitChars() conserve les espaces sous forme de <span> contenant un espace insécable (\u00a0). Chaque espace reçoit son propre --delay, ce qui produit une petite pause naturelle dans le rebond entre les mots.animation-timeline: view() et animation-range sur les .char pour remplacer le toggle de classe. Pour une compatibilité plus large (Firefox, Safari actuels), préférez un IntersectionObserver qui ajoute .active quand le conteneur atteint 20 % du viewport.