Skip to content
animorio
IT
Back to the library

The word coming into register

TextGSAP, CSS onlyMediumCompressed weight: Demo 7.2 KBGSAP 28 KBFreeDownload the zip

A text animation in the minimal style: a big word is cut into thin strips, each one pushed sideways and drawn a little wider or narrower, so it cannot be read. A red hairline runs down the word and every strip it touches comes into register, passes its place by a pixel and goes back; then the strips slide away one after the other and bring the next word, out of register again.

The code

A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>The word coming into register</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-flex@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <!-- the word people read; everything drawn below is only its picture -->
    <h1 class="sr" data-read>Offset</h1>

    <!-- the rig: a column with the word in it. The script cuts the word into thin horizontal strips, each one a
         window on its own copy of the line; a hairline runs down and the strips fall into register behind it -->
    <div class="rig" data-rig aria-hidden="true">
      <div class="guide guide--left" data-guide><i></i></div>
      <div class="guide guide--right" data-guide><i></i></div>
      <div class="line line--whole" data-whole></div>
      <div class="strips" data-strips></div>
      <div class="scan" data-scan><i></i></div>
    </div>

    <!-- an invisible copy of the word, to measure sizes and the baseline -->
    <div class="line line--probe" data-probe aria-hidden="true"></div>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.

16 values to change

Or ask Claude Code for it

With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:

Take “The word coming into register” from Animorio and fit it into my site

What it does

On ivory paper two very thin grey lines draw themselves from the top and mark the edges of a column; on each one the ticks of the cuts pop out with a small snap, one under the other as on a ruler. Into the column, from the sides, one strip after the other, come the pieces of a word: OFFSET, cut into fourteen thin horizontal strips. Every strip is pushed sideways, one to the left and its neighbour to the right, by an amount that swells and shrinks down the word like a wave, and it is drawn a little wider or narrower and lighter: two ghosts of the word interleave, and it cannot be read. Then a red hairline draws itself above the capitals and slowly runs down the word. Every strip the hairline crosses goes back to its place: it slides sideways, takes the right width and its full weight, passes its place by a pixel and comes back, and the strip above, already still, feels the knock. From top to bottom the word comes together behind the line; when it reaches the baseline the line rests a moment under the letters and runs off to the right, and OFFSET is left whole and black. After a breath the strips leave again, one after the other from the top, left and right in turn: the word goes out of the column in pieces and from the opposite sides the next one comes in, PROOF, already out of register, waiting for the line. Then PRESS, and OFFSET again.

How it works

The strips

The word is measured once: the size of the type, the baseline (an empty inline-block placed at the end of the word sits right on it) and the cap height (measureText of an H on a canvas). The cuts are made between the top of the capitals and the baseline, each rounded to the pixel; the first strip reaches up to the top of the line and the last one down to its bottom, so no piece of a letter is left out. Every strip is a window with overflow hidden on a whole copy of the line.

Out of register

Every word has its own out-of-register pattern, made once with a seeded random generator: neighbouring strips go opposite ways, and how far they move swells and shrinks down the word like a wave, with a little noise. On the same wave every strip is wider or narrower on the wdth axis (STRETCH) and lighter on the wght axis. Thanks to the seed every round is identical to the one before.

The hairline and the return

The red hairline runs down with sine.inOut. The moment it crosses the middle of a strip comes from inverting the curve (acos of 1 minus twice the height, divided by pi), and that is when the strip's return starts: a single number from 0 to 1 that gives the slide (power3.out), the width, the weight and the swing of OVERSHOOT pixels past the place, which dies out on its own. The strip above, already in register, takes a share of that swing: the neighbours feel the knock.

Two words per strip

In every strip slides a track with two copies of the line: the word now in the middle and the next one just outside the column, to the right or to the left depending on the strip. Moving the track by a whole column, with expo.inOut and a small delay from one strip to the next, the old word leaves in pieces and the new one arrives already out of register. Then a function puts the new word in the middle copy and the one after it on the track, and it all starts again without a jump.

One state, drawn every frame

The timeline only moves numbers: for every strip the return and the change of word, and the position of the hairline. A function on the GSAP ticker turns them into transform and font-variation-settings and writes only what changes. When every strip is in register a single copy of the word shows in their place, identical to the pixel. The sizes are measured again when the window changes, and the timeline never notices.

Values to change

NameFileDefaultWhat it changes
WORDSscript.js['Offset', 'Proof', 'Press']The words, one after the other: each arrives out of register and the hairline puts it back in place. Short words of similar length read best.
WEIGHTscript.js760The weight of the word in register, from 100 (a hairline) to 1000 (black). Out of register the strips are lighter.
WIDTHscript.js90The width of the word on the typeface's wdth axis: 25 very narrow, 151 very wide.
STRIPSscript.js14How many strips the word is cut into: a few thick ones show at once what happens, many thin ones look like a misregistered print.
SCATTERscript.js0.12How far the strips are pushed out of register, as a share of the width of the word. The column widens to match.
STRETCHscript.js18How much wider or narrower the strips are out of register, on the wdth axis. With 0 they all have the right width and are only pushed.
OVERSHOOTscript.js1How many pixels a strip passes its place by before it stops. 0 stops dead; above 4 it becomes a bounce.
HOLDscript.js1.4How many seconds the word stays in register, whole, before it leaves for the next one.
SPEEDscript.js1The speed of the whole animation: 2 is twice as fast, 0.5 half as fast.

Try them in the Playground

When to use it

For the opening of a site where a single word has to be noticed and the theme is precision: a printer, an art print shop, a design studio, a magazine, a design festival, a brand whose motto is care for detail. It also suits the changing words of a headline (a studio's services, the sections of a portfolio). It wants a heavy, large typeface and plenty of room around it.

On phones

The same animation: the column is measured to fit almost the whole width of the screen, and the strips, the pushes and the hairline come from the size of the word. There are as many strips on a phone too, only thinner. Turning the phone measures everything again without stopping.

With reduced motion

No strips moving and no hairline: the column is already there, the word stays still in register for a few seconds, fades out and the next one fades in in its place.

Pitfalls

  • A cut on a half pixel blurs the edge of two strips, and in register it leaves a pale line across the word. The cuts are rounded to the pixel, and when every strip is still a single copy of the word shows in their place.
  • Cutting only between the top of the capitals and the baseline would leave accents, the tail of the Q and anything that sticks out outside the strips: the first strip reaches the top of the line and the last one its bottom.
  • The column has to hold the widest strip pushed as far as it goes, on both sides: the longest word is measured also at the widest width STRETCH can give, not only at the width in register, or the pieces are cut against the lines.
  • In a timeline, fromTo draws its starting values at once (immediateRender): building three rounds of tweens on the same strips, the last one built put everything out of register before anything started. Every fromTo has immediateRender false.
  • At the end of a round the hairline is on the baseline: if its position is not reset to zero with a set at the start of the next round, it draws itself under the word instead of above it.
  • With a truly random out-of-register pattern every round would be different, and the preview video would never know when the round is over: the generator has a seed, and every word always has the same pattern.

Libraries

GSAP 3.15.0, Roboto Flex (font variabile, assi wght e wdth) 5.3.0.

Compressed with gzip, the three demo files weigh 7.2 KB; the libraries: GSAP 28 KB.

Testing

Tested on 14 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.

All animations