Wave Animation
Chaque lettre ondule de haut en bas en boucle infinie grâce à un délai CSS échelonné — pur CSS, zéro JS pour l'animation.
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'ondulation repose entièrement sur un @keyframes waveContinuous en trois étapes : 0 % et 100 % à translateY(0), et 50 % à translateY(-15px). La courbe ease-in-out donne à la montée et à la descente un rythme naturel, sin-like.
L'animation est assignée à chaque <span> enfant via la règle .text-wave-continuous span { animation: 2s ease-in-out infinite waveContinuous }. Le décalage de phase est injecté en style inline (animation-delay: 0s, 0.1s, 0.2s…) : chaque lettre entre en vague avec 100 ms d'écart sur sa voisine.
Au chargement, le HTML contient déjà les spans pré-construits avec leurs délais. La fonction utilitaire splitText(el, text, step) — référencée dans le IIFE JS — peut reconstruire ces spans à la volée à partir d'une chaîne de caractères : elle boucle sur chaque lettre, crée un <span style="animation-delay:…"> et le réinsère dans l'élément cible.
Le bouton Replay vide l'élément (innerHTML = '') puis rappelle splitText après 50 ms. Ce délai est nécessaire pour forcer le navigateur à recalculer les minuteries CSS — sans lui, les animations redémarrent immédiatement sans respecter leurs animation-delay.
Accessibilité
- Pas de prefers-reduced-motion : la feuille de style ne contient aucun bloc
@media (prefers-reduced-motion: reduce). Sur les systèmes réglés en mode réduit, l'animation continue. Pour désactiver :@media (prefers-reduced-motion:reduce){.text-wave-continuous span{animation:none}}. - Le texte complet reste lisible par les lecteurs d'écran via le contenu textuel de chaque
<span>— aucunaria-hiddenn'est posé dans le code source fourni. Pour éviter une lecture lettre par lettre, ajoutezaria-label="VOTRE TEXTE"sur le parent etaria-hidden="true"sur chaque span enfant. - Contraste : texte blanc (
#fff) sur fond#0a0a0f→ ratio ≥ 18:1, WCAG AAA. - Aucune interaction clavier déclenchée par l'effet lui-même. Le bouton Replay est un
<button>natif, nativement focusable et activable au clavier. - L'effet est 100 % CSS : aucune boucle
requestAnimationFrame, aucun calcul JS continu — impact CPU minimal sur les appareils à batterie.
Compatibilité navigateur
Repose sur CSS @keyframes, transform: translateY() et animation-delay — supportés nativement depuis des années dans tous les navigateurs modernes.
Sans support de <code>@keyframes</code> (navigateurs très anciens), le texte s'affiche statique à sa position de repos — aucune erreur JS, le contenu reste lisible.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="demo-preview">
<span class="demo-text text-wave-continuous"
id="waveContinuousText"
aria-label="VOTRE TEXTE">
<span aria-hidden="true">W</span>
<span aria-hidden="true">A</span>
<span aria-hidden="true">V</span>
<span aria-hidden="true">E</span>
</span>
<button class="replay-btn" onclick="replayWave()">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 |
|---|---|---|
| translateY(-15px) | -15px | Amplitude verticale de la vague dans @keyframes waveContinuous (étape 50%). Augmentez pour une vague plus prononcée, réduisez pour un effet subtil. |
| 2s (durée animation) | 2s | Durée d'un cycle complet dans .text-wave-continuous span { animation: 2s … }. Réduisez à 1 s pour un rythme rapide, montez à 4 s pour un mouvement lent et serein. |
| ease-in-out (timing) | ease-in-out | Courbe de timing. ease-in-out = mouvement naturel ; linear = oscillation mécanique ; cubic-bezier(0.45,0,0.55,1) accentue les extrémités. |
| animation-delay step (0.1s) | 0.1s | Écart de délai entre chaque lettre (3e argument de splitText ou valeur inline). Réduisez à 0.06 s sur les mots longs ; augmentez à 0.18 s pour une ondulation plus dramatique. |
| font-size: 2.5rem (.demo-text) | 2.5rem | Taille du texte. L'effet est plus spectaculaire à grande taille (4–8 rem). Modifiez sur .demo-text ou un wrapper propre à votre contexte. |
| letter-spacing: -0.02em (.demo-text) | -0.02em | Espacement des lettres. Resserré par défaut ; passez à 0.05–0.15 em pour une vague plus aérée où chaque lettre a plus d'espace vertical. |
FAQ
@keyframes waveContinuous et animation-delay gèrent tout. Le JavaScript ne sert qu'à la reconstruction des spans (utilitaire splitText) et au bouton Replay — le retirer laisse l'animation fonctionner si les spans sont déjà présents dans le HTML.<span id="waveContinuousText"> par vos propres <span style="animation-delay: Xs">Lettre</span>, en incrémentant X de 0.1 s par lettre. Ou appelez splitText(el, 'VOTRE TEXTE', 0.1) en JS pour construire les spans dynamiquement.animation-delay se comptent depuis l'insertion de l'élément dans le DOM. Si on remplace les spans sans les retirer, le navigateur continue les minuteries existantes et l'animation ne repart pas à zéro. La suppression + 50 ms de pause forcent un recalcul complet des timers.