How can I get letters to slide in from the top and bottom?


Letters sliding in from top and bottom.

I was watching some movie yesterday, and one of the text effects they used in the intro had text flying in from top and bottom. Although I feel like this version actually looks a little better (see demo.)

run demo


How It Works

This effect has three moving parts: splitting the word into individual letters, assigning alternating directions, and staggering the timing so the letters cascade in one by one.

Step 1: Split the word into spans

The trick starts in JavaScript. Instead of rendering the word as plain text, we loop over each character and wrap it in its own <span>:

word.split("").forEach((char, i) => {
  const span = document.createElement("span");
  span.textContent = char;
  span.classList.add("letter");
  // ...
  container.appendChild(span);
});

This gives us independent control over every letter's position and timing — something you can't do with a single text node.

Step 2: Alternate top and bottom with even/odd

Each letter gets either from-top or from-bottom based on whether its index is even or odd:

span.classList.add(i % 2 === 0 ? "from-top" : "from-bottom");

That's the whole secret to the interleaved look. Letters at positions 0, 2, 4 fall from above; letters at 1, 3, 5 rise from below. The classes map to two keyframe animations that are mirrors of each other — one starts at translateY(-200px), the other at translateY(200px), and both land at translateY(0).

Step 3: Stagger the delay

If all the letters animated at once it would feel like a single blob flying in. The stagger is what makes it feel like a cascade:

span.style.animationDelay = `${i * 0.07}s`;

Each letter waits 70ms longer than the previous one. Tighten this value (say, 0.04s) for a faster sweep; widen it for a more dramatic, drawn-out reveal. All letters start at opacity: 0 in CSS so nothing flashes before its delay fires.

Step 4: The bounce overshoot

A straight ease-out landing feels flat. The keyframe adds a small overshoot past center, then snaps back, giving the letters a satisfying physical "clunk":

@keyframes slideFromTop {
  0%   { opacity: 0; transform: translateY(-200px); }
  60%  { opacity: 1; transform: translateY(10px);   }  /* overshoot */
  80%  {             transform: translateY(-5px);   }  /* bounce back */
  100% { opacity: 1; transform: translateY(0);      }  /* settle */
}

The letter arrives slightly past its target at 60%, rebounds a few pixels at 80%, then settles at 0. The from-bottom keyframe is the vertical mirror of this (negative values become positive and vice versa).

Putting it together

The full effect is pure CSS animations driven by a tiny bit of JS to inject the spans and delays — no animation library needed. To adapt it to your own word, swap out the word string and optionally tune the two knobs: animationDelay multiplier for timing and the translateY overshoot values for the feel of the landing.