TransitionsGratuit

Character Cascade

Un mot découpé en lettres qui montent de 20 px l'une après l'autre, 80 ms d'écart, puis remplacé par le mot suivant toutes les 2,5 s : la seule cascade qui travaille sur le texte lui-même — 2 Ko de JavaScript, vos mots écrits dans le HTML, lu comme un mot entier par les lecteurs d'écran, lettres posées d'emblée si l'utilisateur réduit les animations.

JSTexteCascade

Mis à jour le

Survolez ou cliquez la scène pour interagir

Cet effet est gratuit — la catégorie Transitions en contient 52 au total, dont 9 gratuits. Effect.Labs regroupe 840 effets vanilla. Découvrir la catégorie →

Exemples d'usage

Tour du Morbihan · amateursDIRECT

Prochaine ville-étape

VANNESLORIENT

Étape 4 · 118 kmDépart demain 13 h

① Ville-étape suivante — retransmission d'une course cycliste amateur

QuandÀ l'arrivée de l'étape, le bandeau de la retransmission annonce la ville suivante : « VANNES » s'efface, « LORIENT » s'écrit lettre par lettre au-dessus du kilométrage et de l'heure de départ.
PourquoiLe nom qui s'écrit lettre par lettre annonce la nouvelle étape comme un générique, sans habillage vidéo.
RéglagesLettres en 52 px, graisse 900, italique, espacées de 0,06 em, blanches sur un bandeau noir à 55 % cerclé de jaune ; délai et cycle d'origine (80 ms, 2,5 s) ; mots donnés en enfants du conteneur.
Amphi BBâtiment Lavoisier

Cours suivant

DROITCHIMIE

10 h 15 – 12 h 15 · 1re année

Ouverture des portes 10 min avant240 places

② Matière de l'heure suivante — écran à la porte d'un amphithéâtre

QuandAu changement d'heure, l'écran de l'amphi B passe de « DROIT » à « CHIMIE », avec l'horaire et la promotion dessous ; l'étudiant qui arrive dans le couloir voit le mot s'écrire.
PourquoiUn seul mot à lire de loin : la cascade attire l'œil de l'étudiant qui arrive dans le couloir, sans clignotement.
RéglagesLettres en 64 px, graisse 800, sur un écran noir cerclé de gris ; libellé « Cours suivant » en vert au-dessus ; cycle d'origine ; sur la page anglaise, les mots passent à LAW et CHEMISTRY.

LIBRAIRIE · LA GRANDE MARÉE

Thème du mois

POLARVOYAGE

Les choix de nos libraires sur la table d'entrée

③ Thème du mois — vitrine numérique d'une librairie indépendante

QuandLe 1er du mois, l'écran de la vitrine passe de « POLAR » à « VOYAGE » au-dessus d'une rangée de dos de livres ; le passant voit le mot se former en s'approchant.
PourquoiLe mot qui s'écrit lettre par lettre attire le passant devant la vitrine, comme une affiche qu'on peint.
RéglagesLettres en Georgia 66 px, graisse 700, noires sur papier crème ; rangée de dos de livres en bas ; même délai et même cycle.

Comment ça marche

Le cadre .md-char-stage (250 px de haut, fond #1a1a24) centre .md-char-cascade. Le script y écrit une lettre par span.md-char : 2rem, graisse 700, blanc, display: inline-block pour que la lettre puisse bouger seule. Chaque lettre part invisible et 20 px plus bas, et l'animation mdCharIn la remonte en 0,4 s ; forwards la laisse en place. Le décalage est écrit par le script : animation-delay vaut i × 0,08 s. Un mot de six lettres est entièrement écrit en 0,8 s.

Le script parcourt chaque .md-char-cascade de la page. Il lit ses mots dans les enfants du conteneur — un élément par mot, par exemple <span>VANNES</span><span>LORIENT</span> — et, si le conteneur est vide, prend la liste de démonstration (MOTION, DESIGN, EFFECT, SMOOTH). showWord() vide le conteneur, écrit le mot entier dans un span.md-char-sr invisible à l'œil, puis les lettres, chacune marquée aria-hidden="true" ; une espace devient une espace insécable pour garder sa largeur. Toutes les 2,5 s, le mot suivant prend la place. Un IntersectionObserver ne fait tourner ce cycle que lorsque le bloc est visible ; avec un seul mot, il n'y a pas de cycle, la cascade se joue une fois.

Le cycle automatique est la nature de l'effet : un seul mot à lire, qui change à intervalle régulier, comme un panneau. Les lettres séparées ne gênent pas la lecture assistée : mesuré dans Chromium 151 et Firefox 153, l'arbre d'accessibilité contient « MOTION » d'un seul tenant, pas six lettres. Le cadre a sa propre classe, préfixée comme le reste de l'effet : deux effets de la bibliothèque collés sur la même page ne se réécrivent pas.

Accessibilité

  • Mouvement réduit : sous prefers-reduced-motion: reduce, le CSS pose chaque lettre à sa place, sans montée (animation: none; opacity: 1; transform: none). Le mot continue de changer toutes les 2,5 s, sans mouvement. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : six lettres à opacité 1 à la première mesure.
  • Lecteurs d'écran : le mot entier est écrit dans un span masqué visuellement, et les lettres animées sont cachées aux aides techniques. Mesuré : l'arbre d'accessibilité donne « MOTION », puis « DESIGN » 2,5 s plus tard. Le conteneur n'a pas d'aria-live : un changement toutes les 2,5 s annoncé à voix haute serait épuisant. Si le mot porte une information importante, écrivez-la aussi ailleurs dans la page.
  • Mise à jour automatique : un contenu qui change seul pendant plus de 5 secondes doit pouvoir être mis en pause. Pour un affichage dans une page de lecture, ajoutez un bouton qui arrête le cycle (clearInterval), ou limitez le nombre de tours ; sur un écran d'affichage public (porte de salle, vitrine), le cycle est attendu.
  • Contraste : lettres blanches sur #1a1a24, plus de 15:1 une fois en place ; pendant les 0,4 s de montée, l'opacité grandit de 0 à 1.

Compatibilité navigateur

CSS (@keyframes, transform) + 2 Ko de JavaScript (IntersectionObserver, setInterval), aucune dépendance. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : même cascade, même changement de mot à 2,5 s, même mot entier exposé aux lecteurs d'écran, même pose directe sous mouvement réduit.

Chrome 51+✓ Complet
Firefox 55+✓ Complet
Safari 12.1+✓ Complet
Edge 79+✓ Complet
Mobile iOS 12.2+✓ Complet
Android Chrome 51+✓ Complet

Sans IntersectionObserver, le cycle tourne en permanence. Sans JavaScript, vos mots écrits dans le conteneur s'affichent tels quels, côte à côte et sans animation : gardez le premier mot seul dans le HTML si l'affichage sans script compte, et ajoutez les autres par le script.

Le code

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

HTML
<div class="md-char-stage">
  <div class="md-char-cascade"></div>
</div>
CSS
.md-char-stage,
.md-char-stage *,
.md-char-stage *::before,
.md-char-stage *::after {
  box-sizing: border-box
}

.md-char-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

.md-char-cascade {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.md-char {
  display: inline-block;
  font-size: 2rem;
  font-weight: 700;
  color: #fff;
  opacity: 0;
  transform: translateY(20px);
  animation: mdCharIn 0.4s forwards;
}

@keyframes mdCharIn {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Le mot entier, lu par les lecteurs d'écran, invisible à l'œil */
.md-char-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Mouvement réduit : les lettres sont posées d'emblée, le mot change sans mouvement */
@media (prefers-reduced-motion: reduce) {
  .md-char {
    animation: none;
    opacity: 1;
    transform: none;
  }
}
JavaScript (fx-0731)
(function() {
  // Character Cascade : le mot monte lettre par lettre, puis cède la place au suivant toutes les 2,5 s
  document.querySelectorAll('.md-char-cascade').forEach(function(container) {
    // Les mots : un élément enfant par mot (<span>VANNES</span><span>LORIENT</span>),
    // sinon la liste de démonstration
    var words = Array.prototype.map.call(container.children, function(el) {
      return el.textContent.trim();
    }).filter(Boolean);
    if (!words.length) words = ['MOTION', 'DESIGN', 'EFFECT', 'SMOOTH'];
    var currentWord = 0;
    var intervalId = null;

    function showWord() {
      // Animations mises en pause (bouton Pause de la page, outils d'accessibilité) : on garde le mot affiché
      var first = container.querySelector('.md-char');
      if (first && getComputedStyle(first).animationPlayState === 'paused') return;
      container.innerHTML = '';
      var word = words[currentWord];
      // Le mot entier pour les lecteurs d'écran ; les lettres, masquées pour eux, sont pour l'œil
      var label = document.createElement('span');
      label.className = 'md-char-sr';
      label.textContent = word;
      container.appendChild(label);
      word.split('').forEach(function(char, i) {
        var span = document.createElement('span');
        span.className = 'md-char';
        span.setAttribute('aria-hidden', 'true');
        span.textContent = char === ' ' ? '\u00a0' : char;
        span.style.animationDelay = (i * 0.08) + 's';
        container.appendChild(span);
      });
      currentWord = (currentWord + 1) % words.length;
    }
    showWord();
    if (words.length < 2) return;

    // Le cycle ne tourne que lorsque le bloc est visible
    if ('IntersectionObserver' in window) {
      var obs = new IntersectionObserver(function(entries) {
        if (entries[0].isIntersecting) {
          if (!intervalId) intervalId = setInterval(showWord, 2500);
        } else {
          if (intervalId) {
            clearInterval(intervalId);
            intervalId = null;
          }
        }
      }, {
        threshold: 0
      });
      obs.observe(container);
    } else {
      // Repli : cycle permanent
      intervalId = setInterval(showWord, 2500);
    }
  });
})();

Personnaliser

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

Option / propriétéDéfautEffet
Vos mots (HTML — enfants de .md-char-cascade) aucun : MOTION, DESIGN, EFFECT, SMOOTH Un élément par mot, dans l'ordre d'affichage : <span>DROIT</span><span>CHIMIE</span>. Un seul mot : la cascade se joue une fois, sans cycle.
Écart entre lettres (JS — i * 0.08) 80 ms 40 ms pour un mot long (12 lettres en 0,84 s) ; 120 ms pour un effet machine à écrire. Gardez l'écriture complète sous la moitié du cycle.
Rythme du cycle (JS — setInterval(showWord, 2500)) 2,5 s par mot 4 s pour un affichage à lire de loin ; en dessous de 1,5 s, le mot n'a pas le temps d'être lu après sa cascade.
Montée et durée (CSS — translateY(20px), mdCharIn 0.4s) 20 px, 0,4 s translateY(0.6em) garde la même proportion à toutes les tailles de texte ; rotateX(90deg) à la place donne des lettres qui basculent.
Typographie (CSS — .md-char) 2rem, graisse 700, blanc Toute police marche, chaque lettre étant une boîte inline-block. Les ligatures et l'approche entre paires de lettres sont perdues : préférez les capitales ou une police à chasse régulière pour les grands titres.

FAQ

Un lecteur d'écran lit-il le mot ou les lettres ?

Le mot. Le script écrit le mot entier dans un span.md-char-sr, masqué à l'œil mais lu par les aides techniques, et marque chaque lettre animée aria-hidden="true". Mesuré dans Chromium et Firefox : l'arbre d'accessibilité contient « MOTION » d'un seul tenant. Gardez la règle CSS .md-char-sr si vous changez le style : sans elle, le mot apparaîtrait deux fois à l'écran.

Comment arrêter le cycle après un tour ?

Dans showWord(), après currentWord = (currentWord + 1) % words.length;, arrêtez l'intervalle quand currentWord revient à 0 : if (currentWord === 0) { clearInterval(intervalId); obs.disconnect(); }. Le dernier mot reste affiché. Pour un bouton pause, appelez simplement clearInterval(intervalId).

Et pour une phrase de plusieurs mots ?

Les espaces sont gardées (elles deviennent des espaces insécables), donc « BELLE ÎLE » s'écrit correctement. Mais une ligne de lettres en inline-block ne passe pas à la ligne entre les mots : au-delà de 15 à 20 caractères, réduisez la taille ou découpez la phrase en plusieurs conteneurs, un par ligne.