Say we want to animate a line of text, letter by letter:

You may have found (like I have) that elements positioned with absolute perform better than ones positioned relative, so you could try to split them in to <span>s that are positioned absolutely. Unfortunately, when we add that HTML/CSS, your text now looks like this:

(sad trombone)

When spans have position: absolute; on them, they are no longer are positioned in their natural layout so they end up on top of each other. We could try to fix this by positioning the letters by spacing them evenly along the x plane, using the letter index. Unless we're using a monospace font this will probably look weird as the final text won't match the proper kerning/letter-spacing for the font.

A better (although more complicated) solution is to render the letters in an identical element off-page, and copy the positions of those letters to the ones you plan to animate.

Step 1. create your 'guide' element

We'll want an identical element to the one you're going to animate, except in the guide element the spans are not positioned absolutely (and therefore look normal). In the Pen code below you'll see I have two h2 elements with the same content, but the .animate h2 has spans with absolute positioning.

Step 2. read and copy the x position of your guide spans to your animate spans

We can get any DOM element's position relative to the screen by using the getBoundingClientRect method. By getting the left value of each of our guide spans, we can apply that value to the CSS of our animated spans.

Note: we could also use an element's offsetLeft property to get the same information, but remember offsetLeft stores the left position relative to the element's container rather than the page.

  const placeSpans = () => {
  // for each span in the guide
  for (var i = 0; i < guideSpans.length; i++) {
    let guide = guideSpans[i];
    let animated = animatedSpans[i];
    // get the guide client rect
    let rect = guide.getBoundingClientRect();
    // set the left property of the animate
    // span to rect.left
    animated.style.left = rect.left + 'px';
  }
}

The end result is perfectly, yet absolutely positioned spans.

Step 3. add animation!

Now the spans we plan to animate are absolutely positioned, we can go bananas with transforms. I showed a bit of restraint here and did a simple scale and fade, using the GSAP TweenLite library.

Step 4. hide the evidence

Finally, we don't want anyone to know our clever secret so we'll position our guide text offscreen with CSS, and put the animated text in it's rightful place in the center.

Thanks for reading! If you decide to make a pen using this technique, make sure you share them with us in the comments below :) Happy animating.


4,070 7 88