
The menu that opens from its button
Menus, Transitions, Text
Free
The small basket of a plain stationery shop, in the minimal style: four products set as lines of type, with the quantity, the price and a sign to take them away. Change a quantity and only the digits that change roll, the rightmost first, and the total recomposes itself digit by digit; take a product away and a vermilion hairline strikes it out, then its line folds shut like paper while the others rise on springs; under every new total the rule of the sum is drawn again. Undo unfolds it.
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 basket in lines</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-flex@5.3.0/full.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the small basket of a plain stationery shop, set as lines of type: every product is a line with its price,
its quantity and a sign to take it away. A quantity that changes rolls its figures and the total recomposes
itself digit by digit; a product taken away is struck through with a hairline and its line folds shut like
paper, while the lines under it rise on springs; the rule of the sum is drawn again under every new total -->
<section class="cart" aria-labelledby="cart-title" data-cart data-autoclic>
<header class="cart__head">
<h2 class="cart__title" id="cart-title">Basket</h2>
<div class="cart__side">
<button class="undo" type="button" hidden data-undo>
<svg class="undo__icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M5.5 3.5 2.5 6.5l3 3"/><path d="M2.8 6.5h6.7a3.5 3.5 0 0 1 0 7H7"/></svg>
<span class="undo__word">Undo</span>
<span class="undo__time" aria-hidden="true" data-undo-time></span>
</button>
<p class="cart__count"><span class="roll" aria-hidden="true" data-count-n></span><span aria-hidden="true" data-count-word>items</span><span class="sr" data-count-sr></span></p>
</div>
</header>
<span class="cart__rule" aria-hidden="true" data-head-rule></span>
<div class="lines" data-lines>
<ul class="lines__list" aria-label="Products" data-list></ul>
<p class="lines__empty" aria-hidden="true" data-empty>Nothing in the basket yet.</p>
</div>
<div class="sum" data-sum>
<div class="sum__rule" aria-hidden="true" data-sum-rule>
<svg class="sum__plus" viewBox="0 0 10 10"><path d="M5 1.5v7M1.5 5h7"/></svg>
<span class="sum__line" data-sum-line></span>
</div>
<p class="sum__total">
<span class="sum__label">Total</span>
<span class="sum__figure" aria-hidden="true" data-total-box><span class="sum__cur c" data-cur></span><span class="roll" data-total></span></span><span class="sr" data-total-sr></span>
</p>
<p class="sum__note">Delivery and taxes at the next step.</p>
</div>
<button class="go" type="button" data-go>
<span class="go__fill" aria-hidden="true" data-go-fill></span>
<span class="go__label" data-go-label>Checkout</span>
</button>
<p class="sr" aria-live="polite" data-live></p>
</section>
</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.
41 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 basket in lines” from Animorio and fit it into my siteEvery digit of a figure is a cell as wide as one digit (Roboto Flex has tabular figures, all the same: the width is measured once with a probe) and 1.3 em tall, with overflow hidden and a mask that fades above and below. Inside it there is a strip: at rest one digit, when it changes the digits from the old one to the new one, in the way of the change. GSAP moves the strip with power3.out to one pixel past its place (the overshoot is in pixels, not a share of the run, so it is the same for one step or seven) and then back; at the end the strip goes back to a single digit.
The new figure is matched with the old one from the right, so units meet units and the decimal point stays put. For every position: the same digit does nothing, a different one rolls, CARRY seconds later for each place to the left; one position more opens its cell from zero width and its digit comes in from nothing, one less rolls away and its cell closes. A long way round (7 down to 8) shows only the last four digits of the road: the strip stays short and the figure calm.
Every frame the speed of the strip (digits per second) narrows its digits on the wdth axis by up to NARROW, like a typographic blur; on landing a short tween takes the GRAD axis to 80 and back to zero. Grade thickens the strokes without changing the width, so the cells do not move a pixel while the digit takes weight. The axes live in the strip's font-variation-settings, starting from the width of its figure (the total is narrow, 78).
Taking a product away is a timeline: an element 1.5 pixels tall grows with scaleX from the left across the name's line, then the line folds. Two copies of the line are made, each in a window half as tall: the top half turns on its top edge with rotateX(θ), the bottom one is moved (h/2)·cos θ down and (h/2)·sin θ towards the viewer and turns by −θ, so its bottom edge lands exactly at h·cos θ. The real line, hidden, counts for the layout as exactly h·cos θ; the half turned away from the light darkens a little with the sine of the angle. Undo folds it back the other way and the hairline withdraws.
The lines are absolute and each one has a spring (SPRING, with steps of at most 1/120 of a second and never more than 1/30 a frame) that follows the sum of the heights above it; the further a line is from the one that changes, the softer its spring (RIPPLE), so they rise one after the other and settle with a pixel too many. A line never rides more than a pixel and a half into the one above: a line opening again pushes the others down instead of landing on them. The height of the list, and so the total and the pill, is on a spring too; when nothing moves the loop stops.
The rule of the sum is as wide as the new total, measured on a hidden copy: it goes off to the left and is drawn again from the right, and the plus beside it bounces. The Checkout pill has two springs, the swell (softer, it bounces) and the squash: the fill scales a few pixels past its edges and the word goes from wdth 100 to 124. Everything is real buttons; Delete takes the focused line away, Ctrl or Cmd with Z undoes, the focus goes to Undo and back to the line opened again, and an aria-live region reads the quantity and the total. A click from a script on the basket (detail 0, the library's preview) makes a round: two pluses, a line taken away, Undo, two minuses and the pill pressed.
| Name | File | Default | What it changes |
|---|---|---|---|
ITEMS | script.js | [['Dot grid notebook', 'A5 · 120 g paper', 18, 1], …] | The products: name, the line under it, the price of one and how many. |
CURRENCY | script.js | € | The sign before the prices. |
MAX_QTY | script.js | 9 | The most of one product. |
ROLL | script.js | 0.6 | The seconds a digit takes to roll to its new figure. |
CARRY | script.js | 0.05 | The delay between a digit and the one on its left, like a carry. |
NARROW | script.js | 0.3 | How much a digit narrows on the width axis while it runs fast (0, never). |
STRIKE | script.js | 0.45 | The seconds of the hairline striking a product out. |
FOLD | script.js | 0.6 | The seconds of the line folding shut. |
SPRING | script.js | [300, 28] | The spring of the lines rising: how stiff, and how much it is held back. |
RIPPLE | script.js | 0.35 | How much later the lines further down answer (0, all together). |
UNDO_TIME | script.js | 5 | The seconds Undo stays after a product goes. |
For the side basket or the basket page of a shop with few products and a lot of type: a stationery shop, a bookshop, a coffee or homeware shop, the till of a ticket site; also for any list with quantities and a total (a quote, a table order). It suits three to six short lines; colours and springs change in the variables.
Below 480 pixels the columns tighten (the basket is as wide as the screen less 32, 358 at 390), the name goes down to 15 pixels and ends with an ellipsis if it does not fit, the total to 38. Everything else is the same: the digits roll, the lines fold, the springs are the same. Taps do not wait for a double tap (touch-action manipulation) and on the pill a finger does what the mouse does: it swells and squashes it.
No rolling digits: they change in place. Taking a product away the hairline fades in, the line fades out and the others take its place at once without sliding; Undo fades it back in. The rule of the sum changes width without being drawn again, the pill does not swell, Undo fades in and on opening the basket fades in.
GSAP 3.15.0, Roboto Flex (font variabile, con gli assi della larghezza, del peso e del grado) 5.3.0.
Compressed with gzip, the three demo files weigh 14 KB; the libraries: GSAP 28 KB.
Tested on 16 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.