TexteGratuit

Letter Fade In

Chaque lettre surgit en fondu avec un délai décalé : splitText() enveloppe chaque caractère dans un <span> à animation-delay progressif — une seule keyframe CSS anime l'opacité 0 → 1.

JSCSSStagger
F A D E I N
Survolez ou cliquez la scène pour interagir

Cet effet est gratuit — la catégorie Texte en contient 56 au total, dont 4 gratuits. Effect.Labs regroupe 811 effets vanilla. Découvrir la catégorie →

Exemples d'usage

Bibliothèque Effect.Labs

① Hero de landing — Accroche révélée lettre à lettre

QuandÀ l'atterrissage sur une page produit ou un portfolio, quand le titre principal doit capter l'attention au premier regard.
PourquoiLa révélation progressive crée un micro-moment d'attente qui renforce la lecture du titre et donne l'impression d'un soin apporté à la mise en scène, sans nécessiter de canvas ni de librairie.
RéglagesdelayStep 0,06 s, font-size 4 rem, font-weight 900, letter-spacing 0,05 em, texte blanc sur fond sombre.
👋
Nouvelle connexion détectée
Votre espace est prêt.

② Carte d'onboarding — Prénom révélé à la première connexion

QuandÀ la première connexion d'un utilisateur, dans une modale ou une carte de bienvenue qui affiche son prénom.
PourquoiRévéler un prénom lettre par lettre transforme un texte statique en moment mémorable sans alourdir le composant — l'effet est bref (moins de 0,5 s pour 5 lettres) et ne bloque aucune interaction.
RéglagesdelayStep 0,05 s pour un dévoilement vif, animation-duration 0,4 s, font-size 2 rem, le reste du composant reste statique.
La nuit des origines

③ Titre narratif — Ouverture de chapitre ou cinématique de jeu

QuandDans un jeu, une présentation ou un récit interactif, quand un titre de chapitre ou une phrase clé doit s'afficher de manière dramatique.
PourquoiUn delayStep allongé (0,12 s) ralentit la révélation et crée une tension narrative — chaque lettre devient un battement, comme un générique de film ou un titre de roman graphique.
RéglagesdelayStep 0,12 s, font-size 3 rem, font-weight 700, letter-spacing 0,2 em, couleur ambre sur fond très sombre.

Comment ça marche

La fonction splitText(element, text, delayStep) découpe la chaîne caractère par caractère. Les espaces sont préservés en texte brut ; chaque lettre est enveloppée dans un <span style="animation-delay: Ns">, le délai étant égal à l'indice du caractère multiplié par delayStep (0,05 s dans la signature, 0,08 s dans initFadeIn()). Le résultat est injecté en innerHTML de l'élément cible.

Le CSS assure toute l'animation : .text-fade-in span démarre à opacity: 0 et exécute @keyframes fadeInLetter (opacity: 1 à 100 %) en 0,5 s, easing ease, fill-mode: forwards — chaque lettre reste visible une fois son animation terminée. Les délais décalés produisent mécaniquement la cascade de révélation.

La fonction replayFadeIn() vide le innerHTML, attend 50 ms (pour que le navigateur retire les styles d'animation figés), puis rappelle initFadeIn(). Ce délai minimal est nécessaire : une keyframe forwards reste bloquée sur son état final tant que le nœud existe — vider puis ré-injecter le DOM est le moyen le plus fiable de repartir de zéro.

L'effet est 100 % CSS pour l'animation : aucun requestAnimationFrame, aucun canvas, aucune librairie externe. Le JS sert uniquement à construire le DOM initial et à gérer le replay. La fonction splitText() est générique : elle accepte n'importe quel élément et n'importe quelle chaîne, et peut être appelée plusieurs fois pour animer plusieurs zones de texte indépendantes.

Accessibilité

  • prefers-reduced-motion absent du code source : aucune détection de la préférence système. À ajouter manuellement pour les usages auto-lancés : @media (prefers-reduced-motion: reduce) { .text-fade-in span { animation: none; opacity: 1; } } — les lettres s'affichent alors directement sans transition.
  • Les caractères restent de vrais nœuds texte dans le DOM — les lecteurs d'écran lisent le mot complet normalement, sans épeler lettre par lettre (les <span> ne portent pas de rôle ARIA, ce qui est correct pour du contenu décoratif).
  • Le bouton Replay est un <button> natif, focusable au clavier. Aucun :focus-visible n'est défini dans le code source — à compléter selon la charte du projet.
  • Contraste : l'effet n'impose aucune couleur de texte (héritage du parent). Le ratio de contraste dépend entièrement du fond et de la couleur choisie par l'intégrateur.
  • Le conteneur animé ne porte pas d'aria-label ni de role particulier — le contenu étant du texte réel lisible, c'est correct dans la majorité des cas ; dans un contexte purement décoratif, ajouter aria-hidden="true" sur le conteneur.

Compatibilité navigateur

Animation CSS pure (opacity + animation-delay) et JS vanilla — supportés dans tous les navigateurs modernes. Zéro dépendance externe.

Chrome 80+✓ Complet
Firefox 75+✓ Complet
Safari 13.1+✓ Complet
Edge 80+✓ Complet
Mobile iOS 13+✓ Complet
Android Chrome✓ Complet

Si JS est désactivé, la structure HTML statique préserve les <code>&lt;span&gt;</code> et l'animation CSS fonctionne toujours. Si les animations CSS sont désactivées côté navigateur, les lettres s'affichent directement à <code>opacity: 1</code> — aucune erreur, le texte reste lisible.

Le code

Copiez les trois blocs dans votre page. Aucune dépendance.

HTML
<span class="demo-text text-fade-in" id="fadeInText">
  <span style="animation-delay: 0s">F</span>
  <span style="animation-delay: 0.08s">A</span>
  <span style="animation-delay: 0.16s">D</span>
  <span style="animation-delay: 0.24s">E</span> <span style="animation-delay: 0.4s">I</span>
  <span style="animation-delay: 0.48s">N</span>
</span>
<button class="replay-btn" onclick="replayFadeIn()">Replay</button>
CSS
.demo-text  {
   font-size: 2.5rem;
   font-weight: 800;
   letter-spacing: -0.02em;
   }

.text-fade-in span  {
   opacity: 0;
   animation: 0.5s ease 0s 1 normal forwards running fadeInLetter;
   }

@keyframes fadeInLetter  {
   
  100%  {
   opacity: 1;
   }
}

.replay-btn  {
   position: absolute;
   bottom: 15px;
   right: 15px;
   padding: 8px 16px;
   background: rgba(99, 102, 241, 0.2);
   border: 1px solid rgba(99, 102, 241, 0.4);
   border-radius: var(--radius-md);
   color: var(--primary-light);
   font-size: 0.8rem;
   font-weight: 500;
   cursor: pointer;
   transition: all var(--transition-fast);
   }

.replay-btn:hover  {
   background: rgba(99, 102, 241, 0.4);
   transform: scale(1.05);
   }
JavaScript (fx-0653)
function splitText(element, text, delayStep = 0.05) {
      element.innerHTML = text.split('').map((char, i) => {
        if (char === ' ') return ' ';
        return `<span style="animation-delay: ${i * delayStep}s">${char}</span>`;
      }).join('');
    }

// 1. Letter Fade In
    function initFadeIn() {
      const el = document.getElementById('fadeInText');
      splitText(el, 'FADE IN', 0.08);
    }

function replayFadeIn() {
      const el = document.getElementById('fadeInText');
      el.innerHTML = '';
      setTimeout(() => initFadeIn(), 50);
    }

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
delayStep (3e arg de splitText) 0,08 s Écart de délai entre deux lettres consécutives. 0,04 s = révélation vive, 0,15 s = dramatique et lente.
0.5s ease (propriété CSS animation) 0,5 s, ease Durée et easing du fondu de chaque lettre. Réduire à 0,3 s pour un effet punchy, augmenter à 0,8 s pour un fondu doux. Accepte n'importe quelle valeur CSS (cubic-bezier, ease-out…).
@keyframes fadeInLetter (CSS) opacity 0→1 Seule l'opacité est animée. Ajouter from { opacity:0; transform:translateY(10px) } to { opacity:1; transform:translateY(0) } pour faire glisser chaque lettre vers le haut en fondu.
font-size: 2.5rem (.demo-text) 2,5 rem Taille du texte animé. Adapter à la mise en page : 1,5 rem pour un label, 5 rem pour un titre de hero plein écran.
font-weight: 800 (.demo-text) 800 Graisse du texte. 400 pour un corps de texte subtil, 900 pour un impact maximal.
letter-spacing: -0.02em (.demo-text) -0,02 em Espacement entre lettres. Passer à 0,2 em pour un rendu éditorial large, à -0,04 em pour un titre ultra-compact.
splitText(el, 'VOTRE TEXTE', 0.08) La fonction est entièrement générique : appelez-la sur n'importe quel élément DOM avec n'importe quelle chaîne. Appelez-la plusieurs fois pour animer plusieurs zones de texte indépendamment.

FAQ

L'effet peut-il animer plusieurs textes indépendants sur la même page ?

Oui. splitText() est générique : appelez-la sur autant d'éléments que nécessaire avec des identifiants distincts. Seule initFadeIn() est liée à #fadeInText — pour les autres zones, passez directement l'élément DOM en premier argument : splitText(document.getElementById('mon-titre'), 'MON TEXTE', 0.08).

Pourquoi le délai de 50 ms dans replayFadeIn() est-il nécessaire ?

Une animation CSS avec fill-mode: forwards reste figée sur son dernier état tant que le nœud existe dans le DOM. Vider l'innerHTML supprime les spans, puis les 50 ms laissent le navigateur valider la suppression avant que les nouveaux spans (partant de opacity: 0) soient insérés. Sans ce délai, le navigateur peut recycler les nœuds et ne pas relancer l'animation depuis zéro.

Comment ajouter un glissement vertical (slide up) en plus du fondu ?

Modifiez la keyframe fadeInLetter pour partir d'un décalage vertical : from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); }. Vérifiez que le conteneur parent n'a pas overflow: hidden qui couperait les lettres inférieures, ou ajustez le padding-bottom en conséquence.