100

Inflatable Type

£5

A headline of glossy, air-filled 3D balloon letters on curling ribbon strings. Press one and its surface dents while the rest bulges, sweep across to knock letters into their neighbours with their strings trailing, and tap to pump a letter up until it squeaks back into place.

advanced
8 more details
webgl-shaderspring-physicspointer-effectstouch-gesturestext-animationvelocity-reactiveclick-togglekeyboard-navigation
Inflatable Type - GSAP animation effect preview

This demo reads better at your own screen size than in the frame below:

About this effect

Your headline, inflated. Every letter is built from the font's own outline as a sealed balloon: strokes swell into round tubes, junctions dome higher, and glossy vinyl picks up soft studio reflections and a contact shadow on the wall behind it. Each letter trails a curling ribbon string from its underside, and the whole headline floats with a gentle, out-of-step bob. The letters fill with air in a quick stagger as the page loads.

Read the full effect overview

The letters behave like balloons. Push into one and the surface caves in around your pointer while the rest of the letter bulges and leans away; let go and it springs back with a wobble. A fast sweep knocks letters into their neighbours, which bump softly, swing their strings and float back to a clean, readable headline. Tap a letter to pump extra air in: it swells past its rest size, nudges the letters beside it and squeaks back. The demo ships with "one hundred" and a "100" number-balloon preset; any text in the heading works.

What's included

14 items
  • Letters inflated from the font's real outlines, so any rounded or heavy display face becomes a balloon
  • Local dents that follow the pointer, with a raised rim and a bulge elsewhere in the letter
  • A curling ribbon string tucked under every letter, simulated as a short rope so it lags, swings and settles when the letter moves; one attribute turns strings off
  • Gentle, desynchronised idle float per letter, switchable off
  • Fast sweeps knock letters, which spin, bump their neighbours and spring back to the layout
  • Tap or click to over-inflate a letter, which pushes its neighbours aside and squeaks back to size
  • Glossy vinyl lighting with studio reflections, seam shading and soft contact shadows
  • Staggered inflate on load and a deflate-and-refill when the headline changes
  • Balanced automatic line wrapping that never splits a word, with forced breaks from <br>
  • Touch targets per letter, so press-and-drag works on phones while the empty ground still scrolls
  • Arrow-key letter selection with Enter or Space to pump, plus a live announcement
  • setText(), pump(), poke(), release(), floatAway() and reset() API: floatAway() lets every balloon drift up and away and resolves a Promise when they have gone
  • A transparent overlay option with no wall shadows, for mounting over an existing page
  • Reduced motion keeps the lit 3D letters with calm, non-bouncing responses; a styled headline remains without WebGL or JavaScript

Perfect for

4 use cases
  • A milestone or anniversary announcement: a hundredth issue, a birthday, a launch count
  • A playful product or campaign hero where the headline itself is the interaction
  • A party, event or kids' brand landing page that wants tactile, toy-like type
  • A short brand word or number presented as a giant foil balloon

How it works

1 section

Each character is drawn once to a canvas and converted into a signed distance field and a pressure field, the shape an inflated membrane takes inside that outline. Both are stored in a half-float texture that a three.js shader uses to raise a finely subdivided plane and light it per pixel, so the balloon surface stays smooth at any size. Every letter carries a small set of springs for position, spin, tilt, inflation, dent depth and a quick squash, stepped at a fixed rate so the motion feels the same on any display. Each string is a short verlet rope hung from the underside of its letter, with the curl and twist drawn along it. Pointer input sets the letters' targets and impulses, and neighbours push each other apart when they come closer than their resting spacing. GSAP handles the motion-preference switch, teardown and the staggered inflate on load and on a headline change; the spring simulation and renderer handle every frame in between.

Difficulty Advanced
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this effect's demo, 15 September 2026. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Paid effect

Purchase to unlock the code.

Buying Inflatable Type opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects.

£5 Standard license, unlimited projects

Browse free effects

Documentation

Quick Start

1. Add to your HTML <head>:

Code snippet omitted: it ships with the download.

The inline script is not optional. The heading is the fallback for visitors without JavaScript or WebGL, and without this probe it would paint for the moment it takes three.js to arrive, then be swapped for the canvas. The probe runs before first paint and stamps html.gl when a canvas is coming; the stylesheet hides the typeset heading under that class. The effect removes the class again if it cannot build a renderer.

2. Add the effect HTML:

Code snippet omitted: it ships with the download.

3. Add before the closing </body> tag:

Code snippet omitted: it ships with the download.

three.js 0.180.0 is included in assets/vendor/ (three.module.min.js imports three.core.min.js beside it), so the demo has no third-party request for it. To load it from a CDN instead, point the import map at https://cdn.jsdelivr.net/npm/three@0.180.0/build/three.module.min.js.

Why the import map: three.js ships as ES modules only. The shim imports it, puts it on window, then loads assets/script.js as an ordinary script, so the effect stays a plain file you can drop into any build.

Already using three.js as a module? Skip the shim and make sure window.THREE is set before assets/script.js runs:

Code snippet omitted: it ships with the download.

Using It With Your Own Design

What the effect needs from your markup: a root with data-inflatable-type and, inside it, one element with data-inflatable-type-source holding the headline text. That text is what gets inflated. The script reads the heading's computed font-family, font-weight and font-style, waits for that font to load, and builds the letters from it, so the font you set in CSS is the font the balloons use. Use <br> inside the heading to force a line break; otherwise words wrap onto balanced lines and are never split.

Preset buttons are optional. Any <button data-inflatable-type-text="..."> inside the root swaps the headline to its value and has its aria-pressed kept in step:

Code snippet omitted: it ships with the download.

What is only the demo's styling: the grey studio gradient on .showcase-shell, the cue line, the preset pill and the fallback heading's colour and text shadow. Delete or restyle any of it. Choose the balloon colour with data-color; --accent in the stylesheet only colours the fallback heading, so keep the two in step.

Choosing a font: the effect inflates whatever outline it is given, and it looks best with heavy, rounded display faces (the demo uses Fredoka 700). Thick strokes have room to swell into round tubes; hairline serifs and very thin weights inflate into thin threads. Short headlines read best: one to three words, or a number. On a phone the longest word sets the size, so prefer short words or put them on separate lines.

CSS the effect depends on:

  • The root must have a real size. The canvas is sized from its clientWidth and clientHeight; in the demo it is position: absolute; inset: 0 inside a full-height stage. A root with no height gets a canvas of 0.
  • .gl .inflatable-type__source { visibility: hidden } and the .is-live rule that turns the heading into a visually hidden (but still readable) heading. The heading must stay in the document: it is the fallback and the accessible name of the headline.
  • touch-action: pan-y on the root and touch-action: none on .inflatable-type__hit. The script places an invisible touch target over each letter; together these let a finger press and drag a letter in any direction while vertical swipes on the empty ground still scroll the page.
  • .inflatable-type__focus is the keyboard focus ring drawn round the selected letter; keep a visible style for it.

Options

Attribute Values Default Description
data-color Any CSS colour #ff4a3d Balloon colour
data-puff 0.3 to 1.4 0.85 Height of the inflated surface
data-gloss 0 to 1.5 1 Strength of the studio reflections
data-knock 0 to 2 1 How hard a fast sweep knocks letters; 0 disables knocking
data-idle 0, 1 1 Gentle ambient bob; 0 switches it off (and lets the render loop sleep at rest)
data-intro 0, 1 1 Staggered inflate on load and deflate-and-refill on a headline swap
data-max-size Pixels none Cap on the letter size (font size in px)
data-tracking em -0.01 Extra letter spacing
data-strings off on off removes the ribbon strings (and the room reserved for them below the last line)
data-transparent present absent Overlay use: no contact or string shadows, since there is no wall behind the letters. The canvas is always transparent; the grey ground in the demo is page CSS

Interaction

Input Result
Hover (mouse) A light dent follows the pointer across a letter
Press and hold A deep dent; the letter leans away from the press and bulges elsewhere
Press and drag The dent follows the pointer and the letter is tugged a little way along
Release The letter springs back through its rest with a wobble
Fast sweep Letters in the path are knocked, spin and bump their neighbours, then float home
Tap or click Pumps air in: the letter swells past its size, nudges its neighbours and squeaks back

Every letter hangs a ribbon string tucked under its lowest foot. The string is a short rope simulation, so it trails when a letter is knocked, swings when it spins, and settles after a pump. The layout leaves room for the strings below the last line; their tips fade out, so they may touch the bottom edge on a very short stage.

Accessibility

  • Headline stays text: once the canvas is live, the heading is visually hidden but remains in the accessibility tree as the page's heading. The canvas is aria-hidden.
  • Keyboard: the root is focusable. Arrow keys choose a letter (a ring marks it and a polite live region announces it), Home and End jump to the ends, Enter or Space pumps the chosen letter. Preset buttons are native buttons with aria-pressed.
  • Reduced motion: the lit 3D letters still render, but there is no inflate-in, no ambient bob and no knocking, the strings hang still, and every spring is critically damped: presses and taps give a calm swell and ease back without bouncing. floatAway() becomes a short fade. Switching the preference while the page is open rebuilds the effect in the right mode.
  • Without JavaScript, or without WebGL2: the styled heading shows instead, and the cue line and presets are hidden. One fallback for every failure mode, never hidden until a canvas actually exists.
  • The page is not scroll-trapped: only the letters take the whole touch gesture.

As a Transparent Overlay

The effect can sit over an existing page, for example as a one-off celebration that floats away. Give the root a fixed, full-viewport container, turn off pointer input with CSS if the page underneath must stay clickable (the per-letter touch targets inherit pointer-events: none, and nothing else in the effect depends on pointer input), and take it out of the tab order and the accessibility tree if it is decorative:

Code snippet omitted: it ships with the download.

Code snippet omitted: it ships with the download.

An existing tabindex on the root is kept, so tabindex="-1" removes it from the tab order.

Dependencies

Dependency Version Required
three.js 0.180.0 (included in assets/vendor/) Yes, as an ES module (see Quick Start)
GSAP core 3.12+ (demo pinned to 3.15.0) Yes: motion-preference switching, teardown, and the staggered inflate on load and on a headline swap

No GSAP plugins. A small spring simulation and the renderer own every frame between those played moments. The effect uses long-stable three.js API (WebGLRenderer, PerspectiveCamera, ShaderMaterial, DataTexture, PlaneGeometry), so moving to another version is a one-line change in the import map.

Browser Support

Any browser with WebGL2, which is every current browser. Support is probed before three.js is asked for a renderer, because three.js logs its own failure to the console several times before it throws; a visitor without WebGL2 simply gets the styled heading and a clean console. Browsers too old for import maps never set window.THREE, and also get the heading.

Performance

Four small draw calls per letter (the balloon, its shadow, the string and the string's shadow; two with data-transparent), the balloon a few thousand vertices; the string is a 12-point rope stepped on the CPU; the fragment shader is a handful of texture reads and a procedural studio reflection. Each distinct character is inflated once on the CPU when a headline is built (tens of milliseconds for a typical word) and cached, so repeated letters and swaps back to a previous headline are free. The loop runs only while the root is on screen, and with data-idle="0" it stops entirely whenever the letters are at rest. Pixel ratio is capped at 2 (1.5 on touch devices).

To buy back frames on low-end hardware, set data-idle="0" first so nothing renders between interactions, then keep headlines short: cost scales with the number of letters.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.

Your cart

Your cart is empty

The Vault £99

The Vault library, plus future additions to the library.