
The water button
Buttons, SVG, Physics, Hover
NewFree
A sentence with three words explained, underlined in ink: resting on one, the underline swells round the word, which turns white, and a column of ink rises from it and opens into the tooltip, joined to the word by a soft neck. Going to another word there is no wait: the ink sinks into the first while it rises from the second.
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 tooltip that rises from the word</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/source-serif-4@5.3.0/opsz.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the tooltip that rises from the word: a sentence with three words explained. The ink of a word's underline
swells round the word, and the tooltip rises out of it on a liquid neck; going to another word, the ink sinks
back into the first one while it rises from the next. The ink is painted on the svg, the words on top -->
<div class="gloss" data-gloss data-autoclic>
<svg class="gloss__ink gloss__ink--lines" aria-hidden="true" data-lines></svg>
<svg class="gloss__ink" aria-hidden="true" data-ink></svg>
<p class="gloss__text" data-text>
Fix the <button class="term" type="button" aria-describedby="tip-kerning" data-term><span class="term__word">kerning</span><i class="term__base"></i></button>
in titles, open the <button class="term" type="button" aria-describedby="tip-tracking" data-term><span class="term__word">tracking</span><i class="term__base"></i></button>
and catch every <button class="term" type="button" aria-describedby="tip-widow" data-term><span class="term__word">widow</span><i class="term__base"></i></button>
you set.
</p>
<span class="tip" role="tooltip" id="tip-kerning" data-tip>The space between one particular pair of letters.</span>
<span class="tip" role="tooltip" id="tip-tracking" data-tip>Even space added across a whole run of letters.</span>
<span class="tip" role="tooltip" id="tip-widow" data-tip>A paragraph’s last line, alone at the top of a page.</span>
</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.
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 tooltip that rises from the word” from Animorio and fit it into my siteEvery word has three paths in an svg over the sentence: the underline (in an svg of its own, with no shadow), the ink round the word, and the neck with the tooltip’s body. On every frame the script writes their d attribute again from three springs, ink (the ink round the word), rise (the rise) and wide (the width), worked out on GSAP’s ticker in steps of 4 milliseconds; when the springs are still nothing is drawn again.
Opening, rise starts when ink is past halfway and wide when rise is past halfway; closing they go the other way round, stiffer and without bouncing, so the body narrows, sinks down the neck and then the ink drains into the line. The rise and the width ride the SPRING spring: held back a little, the body goes a bit past its size and comes back, and is a little squashed while it is wider than it should be.
The two sides of the neck are cubic curves that leave the body’s edge level and arrive level on the edge of the word’s ink: they blend in with two soft curves and narrow in the middle to NECK pixels, over GAP pixels of length. At first the upper blend and the near corners are at zero, and neck and body are one column 22 pixels wide with a round tip; as wide grows the body spreads, the neck gets thin and the corners round off.
The word is painted with a gradient cut to its letters (background-clip: text), white up to the height of the ink and blue above it: the stop is a CSS variable the script updates on every frame. The word in use stands over the svg (z-index), the other words of the sentence under it, so the tooltip covers them.
They are real text (role tooltip, and aria-describedby on the word), placed where the body will arrive and as wide as their longest line, measured with a Range. While the body grows, an inset clip-path cuts them to its edges on every frame, so they never stand outside the ink; closing, they go first. The tooltip stays over the sentence, never more than 10 pixels past its sides: if the word is near the edge, the neck stays on the word and the body moves over.
The first time after DELAY seconds of the pointer resting; while a tooltip is out, and for GRACE seconds after, the next one rises at once. Leaving the word it waits LINGER seconds, so the pointer can go up onto it. With the keyboard focus it shows at once, and Esc closes it until the pointer or the focus leave the word; a touch opens and closes it. A click from a script (the library’s preview) is a pretend pointer that passes over the three words and then leaves.
| Name | File | Default | What it changes |
|---|---|---|---|
DELAY | script.js | 0.5 | The seconds the pointer rests on a word before the first tooltip. |
GRACE | script.js | 0.6 | The seconds after a tooltip has gone in when the next one rises without waiting. |
SPRING | script.js | [380, 0.52] | The spring the tooltip rises and spreads on: how stiff it is and how much it is held back. |
GAP | script.js | 12 | How long the neck between the word and the tooltip is, in pixels. |
NECK | script.js | 8 | How wide the neck is at its narrowest, in pixels. |
LINGER | script.js | 0.12 | The seconds the tooltip waits after the pointer has left the word, so it can be reached. |
For glossaries inside an article, the technical terms of a documentation, the items of a contract or an offer (deductible, APR, SLA), the hard words of a lesson: anywhere a word needs one line of explanation without making the reader leave the text.
The sentence goes down to 20 pixels and stays on two lines, so the words on the first line open the tooltip above and those on the second below, without covering the other words explained. A touch opens the tooltip, another touch or a touch somewhere else closes it; the tooltip does not stop the finger, which reaches the word under it. It always stays inside the screen.
No rise, no springs: the ink round the word and the tooltip show already in place with a fade, and in the same time the word goes from blue to white. The underlines are already there, without drawing themselves.
GSAP 3.15.0, Source Serif 4 (font variabile) 5.3.0, Instrument Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 8.7 KB; the libraries: GSAP 28 KB.
Tested on 5 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.