# Inflatable Type

> 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.

Canonical: https://gsapvault.com/effects/inflatable-type
Live demo: https://gsapvault.com/demos/inflatable-type/index.html

| Property | Value |
|----------|-------|
| Type | effect |
| Tier | paid |
| Price | £5 |
| Difficulty | advanced |
| Plugins | Core GSAP only |
| Techniques | webgl-shader, spring-physics, pointer-effects, touch-gestures, text-animation, velocity-reactive, click-toggle, keyboard-navigation |
| Uses Lenis | No |

## Lighthouse, as measured

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

| Category | Score |
|----------|-------|
| Accessibility | 100 |
| Best practices | 100 |

No performance score is published: it depends on the deployment (server compression, caching, CDN, connection and device) rather than on the code, so measure it where it will live.

## Overview

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.

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.

## Features

- 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

## 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

## Vibe-Code Ready Setup

This effect includes `START-HERE-AI.md`, a product-specific copy-paste setup prompt for Cursor, Claude Code, ChatGPT, GitHub Copilot, Windsurf, and other coding assistants. It tells the assistant to inspect the existing stack, integrate the supplied files, preserve the design, scope selectors, retain accessibility and responsive behaviour, add framework-appropriate GSAP cleanup, and report what it tested.

[How AI-assisted setup works](https://gsapvault.com/vibe-coding)

## How It Works

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.

## Documentation

How this effect works and how it goes into a page. The reference you use once you own the files (worked examples, events, the programmatic API, the class list) ships with the download.

### 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.

## What You Get

- `index.html`: working demo page
- `assets/script.js`: commented, readable source
- `assets/style.css`: effect styles
- `README.md`: full documentation with examples and framework integration notes
- `START-HERE-AI.md`: product-specific copy-paste prompt for AI-assisted setup
- `LICENSE.txt`: standard license terms
- Lifetime updates: re-download anytime from your library

## Get the Code

This is a premium effect. The standard license costs £5 one-time and covers unlimited personal and commercial projects with no attribution required for our code. Bundled third-party assets retain their own licences and attribution requirements. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Buy Inflatable Type](https://gsapvault.com/effects/inflatable-type)
- [The Vault (£99 one-time, best value): every collection in the Vault library, plus future items added to those collections](https://gsapvault.com/effects)

## Judge the Code Quality First

These related effects are free with complete source published, written to the same production standard (cleanup functions, reduced-motion support, framework-agnostic):

- [Typewriter Text](https://gsapvault.com/effects/typewriter-text.md): A typewriter that types a line character by character, holds it, accelerates through deletion, and cycles to the next phrase, with optional cursor, status and progress hooks.
- [Scroll Text Highlight](https://gsapvault.com/effects/scroll-text-highlight.md): A scrubbed orange-to-lime reading front lifts each active word before completed copy settles to white and unread copy remains ghosted.
- [Hover Underline](https://gsapvault.com/effects/hover-underline.md): Four material link underlines (an exit-through line, marker sweep, hand-drawn wave, and an endlessly travelling wave) with coordinated type and active-index responses.

---

From [GSAP Vault](https://gsapvault.com): production-ready GSAP animation effects. Full catalog for agents: https://gsapvault.com/llms-full.txt
