Skip to content
animorio
IT
All components

The balloon letters nav

Navigation, Hover, SVG, TextGSAPAdvancedCompressed weight: Demo 11 KBGSAP 28 KBFreeDownload the zip

The top bar of a studio that throws parties: the page you are on is spelled in rose gold mylar balloon letters, puffed up and shiny, with the seam round the edge and a soft shadow under them. Choosing another link the old balloon lets its air out, crumples and goes back to flat text, while the new one fills letter by letter with a bounce and a sway. The light on the foil is not painted: an SVG filter works it out from the shape of the letters.

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 balloon letters nav</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fredoka@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the top bar of a studio that throws parties. The page you are on is spelled in foil balloon letters, blown up
         with the light of real mylar: a filter turns the shape of each letter into a height map and lights it. Choosing
         another link the old balloon lets its air out and goes flat, the new one fills letter by letter -->
    <header class="bar" data-bar>
      <a class="brand" href="#" aria-label="Festoon, home">Festoon</a>

      <nav class="strip" aria-label="Main" data-strip>
        <ul class="list" data-list>
          <li><a class="link" href="#" aria-current="page" data-link><span class="link__word" data-word>Parties</span></a></li>
          <li><a class="link" href="#" data-link data-autoclic><span class="link__word" data-word>Weddings</span></a></li>
          <li><a class="link" href="#" data-link><span class="link__word" data-word>Venues</span></a></li>
          <li><a class="link" href="#" data-link data-autoclic><span class="link__word" data-word>Gallery</span></a></li>
          <li><a class="link" href="#" data-link data-autoclic><span class="link__word" data-word>Contact</span></a></li>
        </ul>
      </nav>

      <a class="cta" href="#"><span class="cta__label">Plan an event</span></a>
    </header>
  </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.

31 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 balloon letters nav” from Animorio and fit it into my site

What it does

On a white background a white bar 64 pixels tall with round corners and a soft shadow: on the left the name Festoon, in the middle five links in a round typeface, Parties, Weddings, Venues, Gallery and Contact, on the right the dark button Plan an event. The links are flat grey text, except the page you are on, spelled in rose gold mylar balloon letters: fat round letters, puffed up, with white highlights along their swell, a darker band where the metal reflects the room, small crimps by the edges, a flat seam all round and a soft shadow on the bar. On arrival all five links are flat and the current one fills one letter after the other: each letter grows, gets heavier, catches the light, goes a little too far and comes back, rises a touch and sways, while the word widens from its middle without one letter covering another. Choosing another link the old balloon lets its air out starting from the last letter: the letters droop, lean a little, sink, crumple and lose their shine until they are flat text again; a moment later the new link fills the same way. With the mouse on a link its letters puff up a little and catch some light; on the current link the balloon swells a touch. Pressing, the link puffs up a little more and the current balloon gets squeezed; clicking the current link the balloon gives a little jump. When nothing moves the filter does no work.

How it works

Letters blown up with a variable font

Every link has an SVG with one letter per text element, twice: a flat copy with no filter and one in the group with the foil filter. Every letter has its own air a, from 0 (flat) to 1 (a balloon) and a little more in the bounce: the scale goes from the size of the flat text (16 pixels) to that of the balloon (26), Fredoka's weight from 460 to 660 and its width from 100 to 108 percent. The foil copy comes in with the air (opacity 2.2·a) and the flat one goes by as much, so the word is always just one.

Letters side by side

The room of every letter is measured once, on the whole word (getStartPositionOfChar, so with the kerning), at the flat weight and the full one. Every frame each letter takes the room it has at its own air and the letters line up, centred: a letter already full pushes its neighbours along instead of covering them, and the word grows from its middle. The link has the width of its word blown up from the start, so nothing around it moves.

The light on the foil worked out by the filter

The filter takes the alpha of the letters, blurs it a little and cuts it with a ramp (feComponentTransfer) to round it like a balloon; then it blurs it by about a tenth of the letter size: that is the height map, a dome inside every stroke. On that dome a diffuse light (feDiffuseLighting, from the top left) goes through a table colour map, dark, rose gold, light, rose gold again, light and white: the band in the middle is the room reflected in the mylar. On top a specular light (feSpecularLighting) is added from a point lamp above the bar, so each letter has its highlight in a different place. Round it, a 0.8 pixel dilation less the shape is the flat seam, and the shape blurred and moved down is the shadow.

Crumples and crimps

A fractal noise (feTurbulence) folded by a zig-zag table becomes a web of creases, multiplied into the dome with an arithmetic feComposite: its weight is 4·a·(1−a), so the crumples are there half way, when the balloon goes flat (fully) or fills (by half), and they are gone when it is full. A second, finer and stretched noise, multiplied by a band near the edge taken from the dome, makes the small crimps by the seams of a full balloon.

The springs

The air of every letter is a spring with its damping worked out from BOUNCE (ζ = −ln B / √(π² + ln² B)) and its frequency from FILL, integrated in four steps a frame in GSAP's ticker, with the step capped at 1/30 of a second. The letters start STAGGER seconds apart; starting they get a push upwards and a turning one, each with its own lightly damped spring: that is the sway. Going flat the spring is critical (no bounce), and half way the letter widens, shortens, leans by 4 to 10 degrees and sinks a few pixels. When every spring is still the loop leaves the ticker and the filter is not drawn again.

Hand, keys and phone

Pointing at a link with the mouse, or reaching it with Tab, its air rises to HOVER; pressing, a little more, and the current balloon goes down to 0.9. The arrow keys move the focus along the links, Home and End go to the ends, Enter and Space choose, and aria-current moves to the new link at once. On a phone the links scroll sideways inside the bar, which fades out on the side where more are hidden, and the chosen link comes to the middle; a finger down gives the mouse's light puff.

Values to change

NameFileDefaultWhat it changes
STAGGERscript.js0.07The seconds between one letter filling and the next.
FILLscript.js0.55About how many seconds a letter takes to fill.
BOUNCEscript.js0.3How far a letter overshoots as it fills, as a share of the way (0, not at all).
DEFLATEscript.js1About how many seconds the old balloon takes to go flat.
HOVERscript.js0.26How much the letters of a link pointed at puff up, from 0 (flat) to 1 (a balloon).
SWAYscript.js6How far the letters sway as the air goes in, in degrees.
SAGscript.js1How much the letters droop and sink as they go flat (0, not at all).
RELIEFscript.js5How deep the balloons look: the height of the relief the light falls on.
SHINEscript.js2How bright the white highlights on the foil are.
WRINKLESscript.js1How crumpled the foil gets half way, going flat or filling (0, smooth).
CRIMPSscript.js0.25How deep the small crimps by the seams of a full balloon are (0, none).

Try them in the Playground

When to use it

For the header of people who throw parties and events: a wedding planning studio, someone who sets up birthdays and baby showers, a balloon and decorations shop, a party venue, a bakery for birthday cakes, an invitations site. It suits a few short links on a light page; the colour of the foil changes in the variables, from rose gold to silver or a bold colour.

On phones

Below 900 pixels the button goes; on a phone the bar is still 64 pixels tall, as wide as the screen less 32 (358 at 390), the letters are smaller (15 pixels flat, 23 blown up) and the links scroll sideways inside the bar, which fades out on the side where more are hidden. The chosen link slides to the middle while the old balloon goes flat and the new one fills; a finger down on a link puffs it up a little, like the mouse. Below 360 pixels the name makes room for the links.

With reduced motion

No filling, no bounce, no sway and no drooping letters: the balloon fades in already full on the chosen link, after the flat word has faded out, and the old one fades out before the flat text comes back, so the two versions are never seen together. Links pointed at only darken, and the button neither grows nor shrinks.

Pitfalls

  • The first filter gave every letter a hammered skin full of blotches: in the arithmetic feComposite the noise was the first input and k2 multiplies just that, so the height was the noise and not the dome. Now the dome is the first input, the noise only comes in with k1 (dome times noise), and with no crumples the light reads the dome directly.
  • With the letters at weight 700 and puffed up by the filter, the eyes of the e closed up and Weddings read Waddings: the full weight is 660 and the ramp that rounds the shape is centred on the real edge of the letter, so it rounds without fattening.
  • Each letter went from its flat place to its full one on its own: a letter already full next to one still flat covered it for a moment. Now the letters line up every frame with the room they have at their own air.
  • With the links as wide as their words blown up, five links, the name and the button did not fit in 900 pixels and Contact ended up outside: the bar is up to 1000 wide and the room round the words is narrower.
  • With less motion the crossfade showed the flat word and the balloon together, one over the other: now one fades out first and then the other comes in.
  • The focus outline drawn close round the link touched the blown up letters: now it runs three pixels outside the link, and the list has four pixels of air at its sides so it is not cut.

Libraries

GSAP 3.15.0, Fredoka (font variabile, con gli assi del peso e della larghezza) 5.3.0.

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

Testing

Tested on 8 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 components