Gradient Letter Flow
Chaque lettre reçoit à tour de rôle le pic de couleur d'une keyframe CSS : une vague lumineuse parcourt le mot de gauche à droite, en continu.
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
Au chargement, le JS récupère le nœud via getElementById('gradientFlowText'), découpe la chaîne caractère par caractère (split('')) et réinjecte chaque lettre dans un <span> avec un attribut style : animation-delay: index × 0,2 s. Le résultat est posé d'un coup via innerHTML. Le HTML peut aussi être pré-rendu côté serveur avec les mêmes attributs pour un affichage immédiat avant JS.
La keyframe gradientFlowLetter (durée 3 s, easing ease-in-out, infinite) anime uniquement la propriété color : elle part du gris de repos #71717a, monte au fuchsia vif #d946ef au mi-cycle (50 %), puis redescend. Un text-shadow glow (rgba(217, 70, 239, 0,5) 0 0 20px) s'allume simultanément au pic pour amplifier l'éclat de la lettre sans affecter le layout.
Grâce aux délais décalés, le pic de couleur visite chaque lettre avec un écart de 0,2 s. Comme toutes les animations partagent la même durée (3 s), leurs phases sont perpétuellement déphasées : certaines lettres sont en montée, d'autres en descente au même instant — ce qui crée l'illusion d'une onde continue qui traverse le mot sans jamais s'arrêter.
Le bouton Replay efface l'innerHTML du conteneur, attend 50 ms (pour forcer le navigateur à recalculer le layout et remettre les animations à zéro), puis réinjecte les spans en appelant initGradientFlow() — relançant la vague depuis la première lettre.
Accessibilité
- prefers-reduced-motion : non géré dans le code fourni — l'animation tourne en boucle infinie quelle que soit la préférence OS. En production, ajoutez
@media (prefers-reduced-motion: reduce) { .text-gradient-letter span { animation: none; color: #d946ef; } }pour figer les lettres sur la couleur peak. - Le texte est du vrai contenu DOM : les lettres restent lisibles par les lecteurs d'écran sans attribut particulier.
- Contraste au repos —
#71717asur#0a0a0f: ratio ≈ 4,6:1 (passe WCAG AA ≥ 4,5:1 pour le texte normal). Au pic fuchsia#d946ef: ratio ≈ 7,3:1 (passe WCAG AAA). - Le bouton Replay est un
<button>natif, focusable au clavier (Tab) et activable par Entrée/Espace. - Aucun
aria-labelniroleposé sur le conteneur : à ajouter si l'élément porte un sens sémantique (ex.role="img" aria-label="Texte animé : GRADIENT").
Compatibilité navigateur
Repose sur les animations CSS natives et des manipulations innerHTML vanilla — supportés dans tous les navigateurs modernes. Zéro dépendance externe.
Si les animations CSS ne sont pas supportées, le texte s'affiche en couleur de repos (<code>#71717a</code>) — 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-gradient-letter" id="gradientFlowText">
<!-- Spans générés par initGradientFlow() ou pré-rendus -->
<span style="animation-delay: 0s">G</span>
<span style="animation-delay: 0.2s">R</span>
<span style="animation-delay: 0.4s">A</span>
<span style="animation-delay: 0.6s">D</span>
<span style="animation-delay: 0.8s">I</span>
<span style="animation-delay: 1s">E</span>
<span style="animation-delay: 1.2s">N</span>
<span style="animation-delay: 1.4s">T</span>
</span>
<button class="replay-btn" onclick="replayGradientFlow()">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 |
|---|---|---|
| color peak (keyframe gradientFlowLetter, 50%) | #d946ef | Couleur au pic de la vague. Remplacez par n'importe quelle couleur CSS pour adapter à votre charte : indigo, or, cyan, rouge corail… |
| text-shadow glow (keyframe gradientFlowLetter, 50%) | rgba(217, 70, 239, .5) 0 0 20px | Halo lumineux autour de la lettre au pic. Augmentez le rayon (30px) ou l'opacité pour un éclat plus dramatique. Mettez none pour désactiver. |
| color rest (keyframe gradientFlowLetter, 0% & 100%) | #71717a | Couleur de base hors animation. Adaptez au fond de votre page : blanc cassé sur fond clair, gris-bleu foncé pour un look premium. |
| animation duration (.text-gradient-letter span) | 3s | Durée d'un cycle complet par lettre. Raccourcissez à 1,5 s pour une vague vive et nerveuse, allongez à 5 s pour un rythme contemplatif. |
| stagger multiplier : i * 0.2 (JS initGradientFlow) | 0.2 | Décalage en secondes entre deux lettres consécutives. À 0,08 la vague est serrée et rapide ; à 0,4 elle est large et solennelle. Ajustez selon la longueur du mot. |
| font-size (.demo-text) | 2.5rem | Taille de la police. Utilisez 1 rem pour un label inline dans une UI, 5–6 rem pour un grand héro plein écran. |
| font-weight (.demo-text) | 800 | Graisse. Les poids lourds (700–900) accentuent le contraste de luminosité entre couleur de repos et pic. |
| letter-spacing (.demo-text) | -.02em | Espacement entre les lettres. Un espacement positif (0,05–0,12 em) laisse de la respiration visuelle et rend les transitions de couleur plus distinctes lettre par lettre. |
FAQ
@keyframes, animation-delay) et une vingtaine de lignes de JS (innerHTML, split, map). Aucune dépendance npm. Copiez le HTML, le CSS et le JS, et l'effet est opérationnel. Compatible React, Vue, Svelte : générez les <span style="animation-delay: Xs"> dans votre composant et appliquez la classe text-gradient-letter.text dans initGradientFlow() (ex. const text = 'DESIGN') — ou générez les spans directement côté serveur ou dans votre framework. Chaque span doit porter style="animation-delay: Xs" avec X = index × 0,2. Adaptez le multiplicateur à la longueur du mot pour garder un étalement cohérent.text-gradient-letter — le nombre d'instances n'est pas limité par le CSS. Côté JS, la fonction cible un id unique (gradientFlowText) pour le replay ; créez autant d'éléments avec des ids distincts et appelez la logique d'initialisation sur chacun individuellement.