
The layered button
Buttons, Hover, Physics
Free
The top bar of an illustration studio, on a strip of fine-grained watercolour paper. The current link sits on a wet stroke of ultramarine: choosing another, a stream of water runs from the old stroke to the new link, the pigment flows after it, and the new stroke flowers at its edge into the cauliflowers of watercolour, while the old one dries to a pale stain with a darker rim and fades. A real simulation of water and pigment on a grid.
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 watercolour nav</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/literata@5.3.0/opsz.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/literata@5.3.0/opsz-italic.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the top bar of an illustrator's studio, on a strip of fine-grained watercolour paper. The current link sits on
a wet stroke of ultramarine; choosing another link a stream of water runs over to it, the pigment flows after
it and the new stroke flowers at its edge, while the old one dries to a pale stain and fades. The paint is a
real simulation of water and pigment on a grid, drawn on a canvas under the words -->
<header class="bar" data-bar>
<canvas class="bar__paper" aria-hidden="true" data-paper></canvas>
<canvas class="bar__paint" aria-hidden="true" data-paint></canvas>
<canvas class="bar__paint bar__paint--old" aria-hidden="true" data-old></canvas>
<canvas class="bar__sheen" aria-hidden="true" data-sheen></canvas>
<a class="brand" href="#" aria-label="Deckle, home">
<!-- a round watercolour brush, its tip loaded with ultramarine -->
<svg class="brand__mark" viewBox="0 0 24 24" aria-hidden="true">
<path class="brand__handle" d="M11.97 12.03 L19.82 4.18"/>
<path class="brand__ferrule" d="M10.7 16.13 L13.21 13.27 L10.73 10.79 L7.87 13.3Z"/>
<path class="brand__tip" d="M3.2 20.8 C5.18 20.52 7.65 19.6 9.14 17.97 L10.59 16.03 L7.97 13.41 L6.03 14.86 C4.4 16.35 3.48 18.82 3.2 20.8Z"/>
</svg>
<span class="brand__name">Deckle</span>
</a>
<nav class="bar__nav" aria-label="Main">
<ul class="bar__list" data-list>
<li><a class="bar__link" href="#" aria-current="page" data-link><span class="bar__word" data-word>Work</span></a></li>
<li><a class="bar__link" href="#" data-link><span class="bar__word" data-word>Prints</span></a></li>
<li><a class="bar__link" href="#" data-link data-autoclic><span class="bar__word" data-word>Workshops</span></a></li>
<li><a class="bar__link" href="#" data-link><span class="bar__word" data-word>Journal</span></a></li>
<li><a class="bar__link" href="#" data-link data-autoclic><span class="bar__word" data-word>Contact</span></a></li>
</ul>
</nav>
<a class="bar__cta" href="#"><span>Commissions</span></a>
</header>
</main>
<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.
22 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 watercolour nav” from Animorio and fit it into my siteA full-resolution canvas, drawn once: the paper's relief is a sum of three value noises at 1.7, 3.6 and 9 pixels; the light comes from the top left, so every pixel is a little lighter or darker as the relief slopes towards it, plus a few wide clouds and about a hundred short fibres. The deckled edge is the distance from a rounded rectangle, moved by more noise, which gives the transparency. The canvas has a still CSS shadow.
A grid of cells every 2 pixels, with the water on the paper, the pigment carried in the water and the pigment already settled into the paper (these two in two layers: the current stroke's and the old ones'). It takes 120 steps a second, with the frame step capped at 1/30 of a second. At every step water passes from a wet cell to the lower neighbour, counting the paper's relief, and takes its share of pigment with it; it wets a dry cell only when it is deeper than that spot of paper's threshold, taken from a lobed noise, so the edges advance unevenly. Pigment also spreads on its own through still water.
Water evaporates, five times faster on cells that have dry neighbours; as it goes down, water flows to the edge to replace what leaves and takes pigment there (a passage of pigment towards the cells nearer the edge, set by EDGES): drying, the edge stays darker. Pigment settles quickly where the water is shallow, and more in the hollows of the paper; when a cell dries, whatever is left settles there.
Choosing a link, everything there is becomes the old layer. The old stroke is wetted again and some of its pigment goes back into suspension; the head of the water runs in RUN seconds, with a speeding up and a slowing down, along a line that goes down out of the old stroke past the end of its word, meanders along the low band of the bar, between the bottom of the words and the edge of the paper, and rises into the new stroke before its word, wetting it. The pigment sets off 0.12 seconds later: every cell behind its front moves it along the line, round the bends too, at the front's speed, sharing it out over the four cells it lands on, so none is lost; the old stroke drains into it more slowly. On arrival the new stroke floods from the side the water comes from and the new pigment fills it.
Near the end where the water came in a bloom opens: a front growing as the square root of time up to a radius that differs in every direction, taken from a noise read round a circle (wide lobes, scallops and a fringe). Only the band just behind the front pushes its suspended pigment one cell further out: the front carries it along and piles it up where it stops, a dark crinkled line round a paler patch; where it passes the edge of the stroke it wets the paper and flowers beyond it.
Every pixel reads the nearby cells after a light blur: the pigment's density becomes colour by the law of Beer and Lambert, channel by channel from --pigment, over the paper with mix-blend-mode multiply; darker in the hollows, with a sharp edge taken from the mask of painted cells. Water darkens the paper slightly and draws a broken line of light along its upper edge, on another canvas. The old layer waits three quarters of DRYING while it dries, and then fades away all together in FADE seconds; the current stroke keeps a film of water (WET). When nothing changes any more the loop stops.
| Name | File | Default | What it changes |
|---|---|---|---|
RUN | script.js | 0.55 | The seconds the stream of water takes to run to the link chosen (a little more for the far ones). |
WATER | script.js | 1 | How much water the brush lays: more, and the new stroke spreads and flowers further. |
BLOOM | script.js | 1 | How much the edge of the new stroke flowers into cauliflowers: 0 a smooth edge, 2 a lot. |
EDGES | script.js | 1 | How much pigment the drying water carries to the edges: 0 none, 2 a dark rim. |
GRANULATION | script.js | 1 | How much the pigment settles in the hollows of the paper: 0 none, 2 a lot. |
DRYING | script.js | 1.3 | The seconds an old stroke takes to dry. |
FADE | script.js | 2.4 | The seconds its pale stain takes to fade away once dry. |
VEIL | script.js | 1 | How wet the paper gets under a link pointed at: 0 not at all. |
WET | script.js | true | The current stroke keeps its wet shine; off, it dries like the old ones. |
For the header of people who work with colour and paper: an illustrator, a watercolour studio, a shop of paints and brushes, a paper mill, an art school, a drawing magazine, an illustrated book. It suits a few short links on a light page; it is a site bar, always at the top.
Below 900 pixels the button goes; on a phone the bar is 60 pixels tall and as wide as the screen less 32 (358 at 390), only the brush is left of the brand and the links shrink down to 12.5 pixels, so all five fit with no scrolling. Strokes and veils get shorter in proportion, the grid is the same: stream, pigment, blooms and stain are those of the computer. A finger on a link wets the paper under the word at once, and lifting it chooses the link, with no wait for a double tap.
No stream, no flow and no blooms opening: the current stroke is already dry, worked out in one go, and fades in; choosing another link the new one, also already dry, fades in while the old one fades out. The veil of water under the link pointed at is there at once, without spreading.
Literata (font variabile, con l'asse della grandezza ottica) 5.3.0.
Compressed with gzip, the three demo files weigh 19 KB, and no libraries are needed.
Tested on 7 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.