Skip to content
animorio
IT
Back to the library

The word that tries on effects

Hover, Text, SVGCSS only, GSAPMediumCompressed weight: Demo 5.7 KBGSAP + CustomEase 31 KBFreeDownload the zip

A sentence and a panel of type blocks: point at a block and one word of the sentence tries that effect on (inflated letters, a glow, the rest out of focus, the word widening) and keeps it until another one is chosen.

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 that tries on effects</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/jetbrains-mono@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- the inflated look: the letters grow fatter, their outline becomes a height map, and a light shines on it -->
  <svg class="filters" width="0" height="0" aria-hidden="true" focusable="false">
    <filter id="puff" x="-30%" y="-30%" width="160%" height="160%" color-interpolation-filters="sRGB">
      <feMorphology in="SourceAlpha" operator="dilate" radius="1.6" result="body" />
      <feGaussianBlur in="body" stdDeviation="3.2" result="height" />
      <feSpecularLighting in="height" surfaceScale="5" specularConstant="1" specularExponent="22" lighting-color="#ffffff" result="light">
        <feDistantLight azimuth="225" elevation="50" />
      </feSpecularLighting>
      <feComposite in="light" in2="body" operator="in" result="lit" />
      <feMorphology in="SourceGraphic" operator="dilate" radius="1.6" result="fat" />
      <feComposite in="lit" in2="fat" operator="arithmetic" k1="0" k2="0.85" k3="1" k4="0" />
    </filter>
  </svg>

  <main class="page">
    <header class="top">
      <p class="brand">Spool</p>
      <p class="top__line">Type blocks</p>
    </header>

    <section class="story">
      <div class="story__text">
        <p class="label">Kinetic type</p>
        <h1 class="line">
          <span class="sr">Give every title a look of its own, then keep it as a block.</span>
          <span class="line__visual" aria-hidden="true" data-line>Give <span data-before>every</span> <span class="word" data-word><span class="word__glow" data-glow></span><span class="word__text" data-text>title</span><span class="word__puff" data-puff></span></span> <span data-after>a</span> look of its own, then keep it as a block.</span>
        </h1>
        <p class="note" data-note>Point at a block to try it on the word.</p>
      </div>

      <div class="panel">
        <div class="panel__head">
          <span class="panel__path">Library / Type blocks</span>
          <span class="panel__close" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M7 7l10 10M17 7 7 17" /></svg></span>
        </div>
        <div class="panel__tiles" role="group" aria-label="Type blocks">
          <button class="block" type="button" data-effect="inflate" aria-pressed="false">
            <span class="block__art block__art--inflate"><span>Aa</span></span><span class="block__name">Inflate</span>
          </button>
          <button class="block" type="button" data-effect="glow" aria-pressed="false">
            <span class="block__art block__art--glow">Aa</span><span class="block__name">Glow</span>
          </button>
          <button class="block" type="button" data-effect="focus" aria-pressed="false">
            <span class="block__art block__art--focus">Aa</span><span class="block__name">Focus</span>
          </button>
          <button class="block" type="button" data-effect="stretch" aria-pressed="false">
            <span class="block__art block__art--stretch">Aa</span><span class="block__name">Stretch</span>
          </button>
        </div>
      </div>
    </section>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/CustomEase.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.

44 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 that tries on effects” from Animorio and fit it into my site

What it does

On the left a large sentence, «Give every title a look of its own, then keep it as a block.»; on the right the dark panel of an editor, «Library / Type blocks», with four blocks, Inflate, Glow, Focus and Stretch, each with an «Aa» showing its effect. Pointing at a block (or tapping it) makes the word «title» try that effect on. With Inflate the word fades and five pastel inflated letters grow in its place, one after another, while the words beside it step aside. With Glow a blue and pink glow lights up behind the word. With Focus the rest of the sentence goes out of focus, more and more the further it is from the word. With Stretch the word widens with a bounce and the rest of the sentence narrows. The effect stays until another one is chosen.

How it works

The sentence in letters

The sentence is split into letters, with each whole word in a span that does not wrap; for every letter the script remembers how many letters separate it from the chosen word. The word has three layers: a glow behind, the text, and on top a row of inflated letters at scale 0.

Inflate

The inflated letters are real letters with an SVG filter: the glyph’s alpha grows by 1.6 px (feMorphology), is blurred by 3.2 px and becomes a height map on which a distant light makes the highlight (feSpecularLighting); the highlight is added to the colour, which has grown too. They grow from scale 0 with back.out(1) over 0.8 seconds, 0.02 seconds apart, from a random ±20° tilt down to 0, while the word underneath fades and the neighbouring words step aside by 0.05 and 0.12 em.

Glow and Focus

Glow takes the glow from scale 1 to 1.35 and from transparent to full over 0.8 seconds; it is a blue and pink radial gradient blurred by 14 px, kept inside the word with isolation: isolate. Focus blurs each letter in proportion to its distance from the word, up to 8 px 16 letters away: the letter turns transparent and the blur is a text shadow of its own colour, which starts at the word and spreads, 0.02 seconds per letter of distance.

Stretch

The typeface’s width lives in two CSS variables, one for the word and one for the rest, read by font-stretch. Stretch takes the word to 120% and the rest to 88% with elastic.out(1, 0.45) over 1.3 seconds: the text reflows every frame and the word bounces on its width.

The panel

With a mouse pointing is enough, with a finger or a keyboard you press: the blocks are buttons with aria-pressed. Every change switches the other three effects off and the new one on over 0.8 seconds; when the page opens, Inflate is tried on by itself.

Values to change

NameFileDefaultWhat it changes
DURATIONscript.js0.8How long every change lasts, in seconds.
LETTER_GAP, TILTscript.js0.02, 20The delay between the inflated letters and how far they tilt before straightening.
SPREADscript.js0.05, 0.12How far the word before and the word after step aside, in em.
BLUR, FALLOFFscript.js8, 16Focus’s greatest blur, in px, and how many letters from the word it is reached.
WIDTHscript.js104, 120, 88The typeface’s width at rest, for the widened word and for the narrowed rest, in percent.
COLOURS, FIRSTscript.js5, inflateThe inflated letters’ colours and the effect tried on when the page opens.

Try them in the Playground

When to use it

For the page of a design tool, a catalogue of effects or typefaces, or a brand that wants people to play with its name. The mechanism, a panel that changes a word’s style, also works for picking a colour, a theme or a tone.

On phones

The panel moves under the sentence with the four blocks in a row, chosen with a tap; the sentence drops to 38 px and the hint asks you to tap.

With reduced motion

The effects change at once, with no growing, bouncing or travelling blur: the result shows straight away.

Pitfalls

  • An SVG filter on a box with a background lights the whole box: put it on the text, where the alpha is the letters’.
  • With z-index −1 the glow ends up behind the body’s background: the word has to be a context of its own, with isolation: isolate.
  • The inflated letters must stay as wide as the word: with a heavier weight or a wider width they push the neighbouring words away, and the neighbours stepping aside is no longer enough.
  • GSAP cannot read a rotation back from a matrix scaled to zero: give the starting scale with gsap.set, not in the CSS.
  • In Safari, filter: blur() on many letters stops at the edge of each letter’s box and rectangles show: with a transparent letter and a blurred text shadow, the blur spreads freely.

Libraries

GSAP 3.15.0, CustomEase (GSAP) 3.15.0, Mona Sans (font variabile) 5.3.0, JetBrains Mono (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 5.7 KB; the libraries: GSAP + CustomEase 31 KB.

Testing

Tested on 28 September 2026

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

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