
The water button
Buttons, SVG, Physics, Hover
NewFree
The menu of a mountain clothing shop quilted like an orange down jacket: pressing Menu, a flat panel unrolls below the button and its channels fill with down one after the other, puff past their size and settle. The light slides on the nylon with the pointer, which presses a dimple into the channel it is on.
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 puffer menu</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">
<!-- the menu of a shop of outdoor clothing, quilted like a down jacket. At rest a glossy orange button with its
stitching. Pressed, a flat quilted panel drops below it and its channels fill with down one after the other,
from the top: each one puffs up with an overshoot and pushes the others down. The light slides on the nylon
with the pointer, and the pointer presses a dimple into the channel it is on -->
<div class="shop" data-frame>
<button class="puff" type="button" aria-expanded="false" aria-controls="puffer-menu" data-toggle data-autoclic>
<svg class="puff__icon" viewBox="0 0 20 16" aria-hidden="true">
<rect data-icon-bar x="1.5" y="1" width="17" height="4.4" rx="2.2"/>
<rect data-icon-bar x="1.5" y="5.8" width="17" height="4.4" rx="2.2"/>
<rect data-icon-bar x="1.5" y="10.6" width="17" height="4.4" rx="2.2"/>
</svg>
<span class="puff__words" aria-hidden="true">
<span class="puff__word" data-word-open>Menu</span>
<span class="puff__word" data-word-close>Close</span>
</span>
<span class="sr" data-toggle-name>Open the menu</span>
</button>
<nav class="quilt" id="puffer-menu" aria-label="Shop" data-menu inert>
<svg class="quilt__fabric" aria-hidden="true" data-fabric></svg>
<ul class="quilt__list">
<li><a class="channel" href="#jackets" data-channel aria-current="page"><span class="channel__name">Jackets</span><span class="channel__note">New season</span></a></li>
<li><a class="channel" href="#fleece" data-channel><span class="channel__name">Fleece</span><span class="channel__note">Mid layers</span></a></li>
<li><a class="channel" href="#base" data-channel><span class="channel__name">Base layers</span><span class="channel__note">Merino</span></a></li>
<li><a class="channel" href="#footwear" data-channel><span class="channel__name">Footwear</span><span class="channel__note">Trail and town</span></a></li>
<li><a class="channel" href="#sale" data-channel><span class="channel__name">Sale</span><span class="channel__note">Up to 40% off</span></a></li>
</ul>
</nav>
</div>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="script.js"></script>
</body>
</html>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.
26 values to change
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The puffer menu” from Animorio and fit it into my siteEvery channel is redrawn each frame from one number, how full it is (from 0 to 1): its height goes from FLAT to the whole of LOFT, its sides bulge with two quadratic curves the more the fuller it is, the seams stay straight and a little drawn in, and the first and last channels have round corners and an outer edge that swells. The channels are stacked: when one grows it pushes the others down.
Every channel has its own spring (PUFF: stiffness and damping), lightly held back, so it goes past its size and settles. When the menu opens the panel unrolls with a clip-path and the springs switch on one every STAGGER seconds from the top; when it closes they switch off from the bottom, then the clip-path rolls everything back up.
Over the flat colour lie three layers with the same shape: a vertical gradient darkening the seams and lighting the round (stronger the more the channel is puffed); a long radial gradient, the gleam, sliding sideways towards the pointer with a soft delay (SHEEN); and the dimple, another radial gradient dark in the middle and light at the rim, following the pointer on a spring of its own.
The channel under the pointer is pressed by PRESS: the dimple darkens, the sides bulge a little more, like air pushed aside, and the link sinks a pixel and a half. Choosing presses hard and gives the channel a knock downwards, which the spring brings back up. The links are real links placed in the middle of their channel; the arrows go from one to the next.
| Name | File | Default | What it changes |
|---|---|---|---|
LOFT | script.js | 62 | The height of a channel full of down, in pixels. |
FLAT | script.js | 0.55 | How tall an empty channel is, against a full one. |
PUFF | script.js | [190, 11] | The springs of the channels filling up: how stiff, and how much they are held back. |
STAGGER | script.js | 0.08 | The seconds between one channel filling and the next. |
PRESS | script.js | 1 | How deep the pointer presses into the down (0 not at all, 2 a lot). |
SHEEN | script.js | 0.55 | How bright the light is on the nylon. |
For the shop of a mountain clothing brand, of down jackets, outdoor gear or winter goods: the menu is made of the material of what you sell. It works with four, five or six links, one for each channel.
The panel narrows to the width of the screen and the channels puff up the same way; a tap chooses the link. Without a pointer the gleam stays still and the dimple shows only when choosing.
No channels puffing up and no springs: the panel fades in already full of down and fades out the same way. Under the pointer the dimple and the light change without moving anything.
GSAP 3.15.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 8.7 KB; the libraries: GSAP 28 KB.
Tested on 19 October 2026
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.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.