Letter-by-Letter Text Reveal

Partager

The letter reveal effect gives your headings a modern and eye-catching look: each letter appears one after another on scroll, just like in the animated intros of creative websites.

1. Add the Code in Elementor

  1. Go to Templates → Custom Code.
  2. Click on Add New Code.
  3. Paste the following code and place it in </body> – End :
<script src="https://unpkg.com/split-type"></script>

<style>
/* Empêche les sauts verticaux lors des masques */
.textLetterReveal .elementor-heading-title .line {
  overflow: hidden;
}

/* Chaque lettre est animée individuellement */
.textLetterReveal .elementor-heading-title .char {
  display: inline-block;
  will-change: transform, opacity;
}

/* Animation quand .fadeIn est ajouté */
.textLetterReveal.fadeIn .elementor-heading-title .char {
  transform: translateY(100%);
  opacity: 0;
  animation: tlr-goUp 0.9s cubic-bezier(0, 0, 0.24, 1.02) forwards;
  transform-origin: 0 100%;
}

/* Animation verticale */
@keyframes tlr-goUp {
  0%   { transform: translateY(100%); opacity: 0; }
  20%  { opacity: 0; }
  30%  { opacity: 0.4; }
  100% { transform: translateY(0); opacity: 1; }
}

/* Variante avec rotation (si tu veux tester) */
@keyframes tlr-goUpTwist {
  0%   { transform: translateY(100%) rotate(8deg); opacity: 0.2; }
  20%  { opacity: 0; }
  30%  { opacity: 1; }
  100% { transform: translateY(0) rotate(0); opacity: 1; }
}
</style>

<script>
document.addEventListener('DOMContentLoaded', function () {
  var speedOfCharAnimation = 0.02; // vitesse entre lettres (0.02 = 40ms)

  var containers = document.querySelectorAll('.textLetterReveal');

  var io = ('IntersectionObserver' in window) ? new IntersectionObserver(function(entries){
    entries.forEach(function(entry){
      if (entry.isIntersecting) {
        entry.target.classList.add('fadeIn');
        io.unobserve(entry.target); // joue une seule fois
      }
    });
  }, { threshold: 0.2 }) : null;

  containers.forEach(function(container){
    var heading = container.querySelector('.elementor-heading-title');
    if (!heading) return;

    var splitter = new SplitType(heading, { types: 'lines, chars' });

    function applyCharDelays() {
      var chars = heading.querySelectorAll('.char');
      chars.forEach(function(char, i){
        char.style.animationDelay = (i * speedOfCharAnimation) + 's';
      });
    }
    applyCharDelays();

    var lastW = window.innerWidth;
    window.addEventListener('resize', function(){
      if (window.innerWidth !== lastW) {
        splitter.revert();
        splitter = new SplitType(heading, { types: 'lines, chars' });
        applyCharDelays();
        lastW = window.innerWidth;
      }
    });

    if (io) {
      io.observe(container);
    } else {
      container.classList.add('fadeIn');
    }
  });
});
</script>

Prepare your Heading in Elementor

  1. Add a Heading widget.
  2. Go to Advanced → CSS Classes and add: textLetterReveal
  3. Add a simple entrance animation (e.g., Fade In) in Elementor.
    👉 This prevents the display bug on appearance (letters visible before animation).

Expected Result

  • On load or when the heading enters the viewport:
    → each letter appears one after another with a smooth effect.
  • The animation plays only once (but you can replay it by removing io.unobserve(entry.target) from the code).

Customization

You can adjust:

Speed between letters: var speedOfCharAnimation = 0.02; → set 0.05 to slow down, or 0.01 to speed up.

Animation type: Replace tlr-goUp with tlr-goUpTwist for a rotation effect.

Trigger: In IntersectionObserver, modify the threshold: 0.2 (20% visible before triggering).

Categorie
Compatible
WordPress, Elementor
Mis à jour
17 Sep 2025

Créer avec Elementor

Hébergez, créez et développez le site web de vos rêves avec la première plateforme pour WordPress.

Inspirez vos projets Elementor avec 1 animation par semaine.

Merci de ton inscription !

Créer avec Elementor

Hébergez, créez et développez le site web de vos rêves avec la première plateforme pour WordPress.