Skip to content
animorio
IT
Back to the library

The headline rewritten by the caret

TextGSAP, CSS onlyAdvancedCompressed weight: Demo 8.6 KBGSAP 28 KBFreeDownload the zip

A text animation in the minimal style: a copywriting studio edits its own headline in front of you. The text caret, a thin bar, glides to a word and selects it with a highlight that opens on a spring; the word is deleted by squeezing on the width axis of the typeface, and the new one is typed letter by letter, opening up. Three edits in a row, from «Make it louder.» to «Say it once.».

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 headline rewritten by the caret</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-flex@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <!-- one headline, edited in front of you: the script builds every letter it will ever need, the caret and the
         selection, and places them from the middle of the page -->
    <h1 class="line" data-line>
      <span class="sr" data-sr>Say it once.</span>
      <span class="highlight" data-highlight aria-hidden="true"></span>
      <span class="letters" data-letters aria-hidden="true"></span>
      <span class="caret" data-caret aria-hidden="true"></span>
    </h1>

    <footer class="foot" aria-hidden="true">
      <span class="foot__brand">Plainword</span>
      <span class="foot__count"><span class="foot__num" data-count>0</span> characters</span>
    </footer>
  </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.

19 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 headline rewritten by the caret” from Animorio and fit it into my site

What it does

On warm white paper, in the middle, a thin bar grows: the text caret. It blinks once and types «Make it louder.»: every letter appears narrow and light, opens a little past its width, comes back and takes its weight, with the uneven rhythm of a hand on the keys; the line stays centred, chasing its place on a spring. The caret blinks, then glides to the end of «louder» and selects it backwards: the vermilion highlight opens on a spring, passes the word by a hair and comes back, and the letters under it turn paper-coloured. A moment later the word is deleted by squeezing, its last letter first, until only the caret is left, and «clearer» is typed in its place. The second edit selects «Make» like a double click, from the middle out to both sides, and types «Say»; the third selects «clearer» forwards, from its start, and types «once». On the last line, «Say it once.», the full stop gives a little hop and lights up in vermilion. Then the caret selects everything, the sentence squeezes into it, the caret retracts and it all starts again. At the foot of the page the studio’s name and the character count, which ticks up or down with every letter.

How it works

The versions and the edits

SENTENCES is the list of versions of the headline. Every version is split into words, spaces and punctuation; between two versions the words that match at the start and at the end stay, and the ones in the middle are the edit: they are selected and replaced. Every letter that will ever appear is made only once, in the order of the line: the deleted ones stay in place with zero width, and the new ones are inserted right after them. So the timeline knows every position in advance, repeats and can be rewound.

Every letter measured along the axis

Roboto Flex has a width axis from 25 to 151. For every letter the advance is measured at 15 widths, light and at full weight, together with the kerning of every pair that stands side by side in some version. On every frame the advance is read from the table (interpolating on width and weight), multiplied by the letter’s presence, from 0 to 1, and summed: the letter’s cell moves with translate3d and squeezes with scaleX from its left, with the font-variation-settings of the moment.

Typing and deleting

When typed, every letter goes from presence 0 to 1 in a sixth of a second, and its width from the value of SQUEEZE to full width with a damped spring written as an ease (it passes the goal by a share set by BOUNCE and comes back exactly there); its weight rises by 260. The timing follows an uneven rhythm, a little slower around spaces. Deleting does the opposite: the width drops, then the presence, from the last letter to the first.

The caret and the selection

The caret and the selection live on the boundaries between letters (the left edge of each), worked out again on every frame: so they follow the line as it moves. The selection runs from boundary A to B and opens from a point (the end, the middle or the start of the word) on a spring. The caret travels to that point, then hangs on the moving edge. The paper-coloured copy of every selected letter is cut with clip-path to the selection, in the letter’s own pixels: the edge stays sharp even halfway through a letter.

The centred line and the final mark

The line wants to stay centred: its position chases half of the total width on a real spring, integrated in steps of 1/240 of a second, so when a word grows or squeezes the sentence moves with a little settle. On the last version the last mark (the full stop) hops by a tenth of a line and comes back on a spring, while its colour turns vermilion with color-mix. The caret’s blink is timeline sets every 0.53 seconds: the whole direction is one GSAP timeline that repeats.

Values to change

NameFileDefaultWhat it changes
SENTENCESscript.js['Make it louder.', 'Make it clearer.', 'Say it clearer.', 'Say it once.']The headline, then the headline after every edit. Between one version and the next the words that change are replaced; it looks best when a single word changes.
WEIGHTscript.js620The weight of the headline, from 100 (a hairline) to 1000 (black).
TYPINGscript.js13How many letters are typed per second.
HOLDscript.js1.4How many seconds every version stays before the caret moves.
BOUNCEscript.js0.5How far the selection, the new letters and the line go past their place before they settle: 0 not at all, 1 a lot.
SQUEEZEscript.js25How narrow a word gets before it disappears, on the width axis: 25 becomes a thread, 100 does not squeeze.
SPEEDscript.js1The speed of the whole animation: 2 is twice as fast, 0.5 half as fast.
LOOPscript.jstrueWhether at the end everything is deleted and the headline is typed again. With false it stays on the last version.

Try them in the Playground

When to use it

For the opening headline of a copywriting studio, a content agency, a writing blog or an editing service: it tells the work of whoever writes, one edit after the other. It works with short sentences where one word changes at a time.

On phones

The same animation on one line: the type is sized so that the longest version fits in nine tenths of the screen, starting from a slightly narrower width (84 instead of 100) to keep the letters large. Caret, selection and springs stay the same, in proportion.

With reduced motion

Nothing slides and nothing squeezes: every version fades in already typed, with the caret still at the end; the selection fades in on the word that will change, then the line fades out and back in corrected. The final full stop lights up in vermilion without hopping.

Pitfalls

  • Comparing the words of the old version (objects with their letters) with the new ones (plain strings) always gave «different»: the first edit selected the whole sentence and typed it again from scratch. The comparison has to be text with text.
  • Between «r» and «.» Roboto Flex tightens the pair: the boundary between the two letters falls inside the «r», and the selection left out half of the letter. The selection ends where the letter ends, without the kerning with the next one, and the caret sits halfway through the kerning.
  • The spring of the selection, passing the word, covered half of the full stop and turned it paper-coloured: it looked like a bug. Now the light copy appears only on the selected letters, and the overshoot is a few pixels.
  • Between the end of one round and the start of the next the caret stayed alone on the page for three seconds, and it looked over: with shorter timings around the restart, the gap lasts little more than a second.

Libraries

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

Compressed with gzip, the three demo files weigh 8.6 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