Skip to content
animorio
IT
Back to the library

The sentence that raises its voice

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

A text animation in the minimal style: a short sentence in small letters stands on the three hairlines of the type, the baseline, the x-height and the cap line. One letter at a time crouches a hair, springs up to the cap line, passes it by a pixel and settles, and its neighbours slide aside to make room. When the whole sentence is in capitals the cap line lights up in the accent colour; then it goes out and the letters drop back to small, from the last to the first.

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 sentence that raises its voice</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <!-- the sentence people read; everything drawn below is only its picture -->
    <h1 class="sr" data-read>say it louder</h1>

    <!-- the rig: three hairlines of the type (cap height, x-height, baseline) and the sentence standing on them.
         The script splits the sentence into letters, each with its small and its capital form -->
    <div class="rig" data-rig aria-hidden="true">
      <div class="rule rule--cap" data-rule>
        <i class="rule__line"></i>
        <i class="rule__lit" data-lit></i>
        <span class="rule__label" data-label>cap height</span>
      </div>
      <div class="rule rule--x" data-rule>
        <i class="rule__line"></i>
        <span class="rule__label" data-label>x-height</span>
      </div>
      <div class="rule rule--base" data-rule>
        <i class="rule__line"></i>
        <span class="rule__label" data-label>baseline</span>
      </div>
      <div class="phrase" data-phrase></div>
    </div>

    <!-- an invisible letter, to measure widths and the baseline -->
    <span class="probe" data-probe aria-hidden="true"></span>
  </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.

15 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 sentence that raises its voice” from Animorio and fit it into my site

What it does

On ivory paper three hairlines draw themselves from the left, one after the other: at the bottom the baseline, black; above it the x-height, grey; higher up, dashed, the cap line. On the right, small, each carries its name: baseline, x-height, cap height. The letters of a sentence in small letters, say it louder, rise onto the baseline one after the other and land with a pixel too many. Then, from the left, one letter at a time raises its voice: it crouches a little, as if to take a run-up, and springs up into its capital; in flight it is a little narrower and lighter, it reaches the dashed line, passes it by a pixel and comes back down to rest, taking its full weight. The capital is wider than the small letter, so the neighbours slide aside to make room: the ones before to the left, the ones after to the right, and the sentence stays in the middle. When the last letter has arrived, the cap line lights up blue from left to right, its name turns blue, and every letter the light reaches takes a little more weight for a moment. SAY IT LOUDER stays like that for a breath; then the blue line runs off to the right and the letters go back to small, from the last to the first, dropping onto the x-height with a small squash. And it starts again.

How it works

The lines of the type

The x-height and the cap height are measured on a canvas with measureText, from the x and the H (actualBoundingBoxAscent). The baseline is found with an empty inline-block placed next to a letter: it sits right on it. The three hairlines go at those heights, on half a pixel, so a one-pixel line stays sharp.

Two forms for every letter

The sentence is split into letters and each letter has a place with two spans inside: the small letter and the capital, centred and hung from the baseline (transform-origin at the height of the baseline). The widths of the two forms are measured once, with their letter spacing (capitals want a little more).

One number per letter

Every letter has a single number g, 0 small and 1 capital. From g come the height (from the x-height to the cap line), the scale of the two forms, the crossfade between them while the letter is at its fastest, and its width. Adding up the widths gives the positions, with the sentence always centred: the neighbours move by themselves.

The spring with a pixel too many

The rise is a home-made curve, 1 minus e to the minus kt times the cosine of wt: it passes 1 only once and settles. The damping k is worked out so that the pass is exactly OVERSHOOT pixels above the cap line. Before the spring there is a small crouch, and in flight the wdth and wght axes of the variable typeface dip and come back: the letter stretches upward and then takes its weight.

The line that lights up

A single looping GSAP timeline directs it all: the letters one after the other, the blue line running with power3.inOut, the return to small letters from the right. The moment the blue line reaches a letter comes from inverting the power3.inOut curve, and that is when the letter takes weight. A function on the ticker draws everything and writes only what changes.

Values to change

NameFileDefaultWhat it changes
PHRASEscript.js'say it louder'The sentence: short, on a single line. It shows in small letters and then in capitals; the size fits the width by itself.
WEIGHTscript.js560The weight of the letters, from 100 (a hairline) to 900 (black). In flight they are a little lighter.
WIDTHscript.js92The width of the letters on the typeface's wdth axis: 62 very narrow, 125 very wide.
STEPscript.js0.13The seconds between one letter growing and the next. With 0 they all grow together; with half a second you follow every letter.
OVERSHOOTscript.js1.5How many pixels the capital passes the cap line by before it settles. 0 arrives dead; above 6 it becomes a bounce.
HOLDscript.js1.6How many seconds the sentence stays all in capitals, with the line lit, before it goes small again.
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 a headline that has to be heard without shouting from the start: the opening of a campaign, a product launch, a festival, a radio station or a podcast, a school of typography or communication, a manifesto page. It works with short sentences that move well from a low tone to a high one (say it louder, make it big, speak up). It wants plenty of room around it and a single line.

On phones

The same animation: the sentence in capitals is measured to fit almost the whole width of the screen, and the lines, the spring and the extra pixel come from that size. The names of the lines appear only if there is room to the right of the sentence, so on a phone held upright they stay hidden. Turning the phone measures everything again without stopping.

With reduced motion

No letters jumping and no lines running: the lines are already there, the sentence in small letters stands still, fades out and comes back in capitals with the cap line lit; after a few seconds it fades again and comes back small.

Pitfalls

  • A capital that suddenly appears in place of the small letter catches the eye. The crossfade between the two forms happens while they are the same height (the capital starts as big as the x) and only in the fastest stretch of the spring: there the eye reads a movement, not a swap.
  • The ascenders of l, d, t are taller than the cap line: if the small letter stretches as much as the capital grows, it overshoots the line while it fades. The small letter stretches only a third and fades early.
  • With a spring like elastic.out the bounce changes with the height of the jump: on a phone, where the jump is a few pixels, it would disappear, on a large desktop it would turn into a cartoon. The curve is home-made and the damping is worked out from the pixels wanted past the line.
  • A one-pixel line placed on a whole number falls across two pixels and turns grey and thick. The lines sit on half a pixel; the blue one, two pixels thick, sits above the line, so the capitals do not cover it.
  • In a timeline, fromTo draws its starting values at once (immediateRender): building the rise and the fall of the same letters, the last one built turned them back into capitals before anything started. Every fromTo has immediateRender false.
  • The space between the words has no capital, but with capitals around it, it looks tight: it widens slowly with the average of the letters already grown.

Libraries

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

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

Testing

Tested on 16 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