
The card room
3D, Transitions, Images
Free
A minimal page change: the page is a sheet printed on both sides, lying on a table. On a click it lifts by the corner, turns over in 3D and the new page is the one printed on its back; it comes down on a thin cushion of air, glides the last few pixels into place and settles with a small bounce, while the title takes its weight like ink under the press.
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 flip-side transition</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/newsreader@5.3.0/opsz.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage" data-stage>
<div class="deck" data-deck>
<!-- on the table, under the sheet: its shadow and the two hairlines of air pushed out when it lands -->
<span class="shadow" data-shadow aria-hidden="true"></span>
<span class="air" data-air aria-hidden="true"></span>
<span class="air air--soft" data-air aria-hidden="true"></span>
<!-- the lifter hinges on the corner that stays down; the sheet turns on its middle; the two pages are its two sides -->
<div class="lifter" data-lifter>
<div class="sheet" data-sheet data-on="a">
<section class="face face--a" data-page="a" aria-label="Prints">
<header class="bar">
<span class="brand">Folium</span>
<nav class="nav" aria-label="Pages">
<a href="#prints" aria-current="page">Prints</a>
<a href="#studio" data-go="b">Studio</a>
</nav>
</header>
<div class="hero">
<p class="kicker" data-rise>Letterpress on cotton paper</p>
<h1 class="big" data-big>Recto.</h1>
<a class="go" href="#studio" data-go="b" data-autoclic data-rise>
<span class="leaf" aria-hidden="true"><span class="leaf__in"><span class="leaf__f"></span><span class="leaf__b"></span></span></span>
<span class="go__text">Turn it over</span>
</a>
</div>
<footer class="foot">
<span>Cards and prints, set by hand</span>
<span>Since 2014</span>
</footer>
<span class="trim trim--tl" aria-hidden="true"></span>
<span class="trim trim--tr" aria-hidden="true"></span>
<span class="trim trim--bl" aria-hidden="true"></span>
<span class="trim trim--br" aria-hidden="true"></span>
<span class="face__shade" aria-hidden="true"></span>
</section>
<section class="face face--b" data-page="b" aria-label="Studio" aria-hidden="true">
<header class="bar">
<span class="brand">Folium</span>
<nav class="nav" aria-label="Pages">
<a href="#prints" data-go="a">Prints</a>
<a href="#studio" aria-current="page">Studio</a>
</nav>
</header>
<div class="hero">
<p class="kicker" data-rise>The other side</p>
<h2 class="big big--b" data-big>Verso.</h2>
<div class="below">
<p class="lede" data-rise>Every card has two sides. This is the quiet one: two old presses, a long table and four people who still set the type by hand.</p>
<a class="go" href="#prints" data-go="a" data-autoclic data-rise>
<span class="leaf" aria-hidden="true"><span class="leaf__in"><span class="leaf__f"></span><span class="leaf__b"></span></span></span>
<span class="go__text">Back to the front</span>
</a>
</div>
</div>
<footer class="foot">
<span>Open on Thursdays</span>
<span>Since 2014</span>
</footer>
<span class="trim trim--tl" aria-hidden="true"></span>
<span class="trim trim--tr" aria-hidden="true"></span>
<span class="trim trim--bl" aria-hidden="true"></span>
<span class="trim trim--br" aria-hidden="true"></span>
<span class="face__shade" aria-hidden="true"></span>
</section>
</div>
</div>
</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.
30 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 flip-side transition” from Animorio and fit it into my siteThe two pages are the two sides of the same sheet: two sections one on the other inside a container with transform-style: preserve-3d, each with backface-visibility: hidden. The side underneath has rotateY(180deg), so it only shows once the sheet has turned half a turn. At the end of the turn the sheet goes back to zero and the two sides swap roles (the data-on attribute): the page in view has no 3D rotation at all and its type stays sharp.
The sheet sits inside a second container, the lifter, with its transform-origin on the corner that stays down (top left going forward, top right going back). The lifter turns PINCH degrees on two axes and the opposite corner rises; then it goes back to zero while the sheet, turning on its middle, rises by HEIGHT and turns 180 degrees. Meanwhile the view steps back (scale to LIFT) to show the table.
During the turn the sheet rises with power2.out and drops with power1.in, twists by TWIST degrees and back, tilts back a little like a sail and drifts sideways. The perspective is 3.2 times the longer side of the screen, and the greatest height is worked out so that the side coming towards the viewer, when the sheet is edge-on, never grows taller than the stage. The shadow on the table is a blurred rectangle that moves and spreads with the height and narrows with the cosine of the turn: edge-on it is a line.
The sheet arrives a few pixels above the table, a little off its place and a little askew. Its height goes to zero with elastic.out(1, 0.42): the air brakes it, pushes it up a hair and lets it settle. Its position and twist come back with back.out, which overshoots by about a pixel. Two one-pixel frames under the sheet open and fade: the air slipping out from the edges. AIR sets all of it at once, 0 = the sheet just lands.
The letters of the new title start thin (font-weight 200 or 300) and take their weight one after another from the side that touched first, with a small two-pixel knock downwards and a spring. Each change is one timeline, with timeScale for SPEED; a click that comes during the turn waits in a queue. On a phone the sheet is tall and narrow and the titles fit the width. With reduced motion nothing turns: the old page fades out and the new one fades in.
| Name | File | Default | What it changes |
|---|---|---|---|
LIFT | script.js | 0.78 | How big the sheet stays while it is in the air: the view steps back to show the table. Above 0.8 the sheet, edge-on, would leave the stage. |
TURN | script.js | 1.1 | The seconds the sheet takes to turn over. |
HEIGHT | script.js | 0.08 | How high the sheet is lifted, as a share of the page width (the script keeps it inside the stage anyway). |
TWIST | script.js | 5 | The degrees it twists while it turns, as if it were held by the corner. |
AIR | script.js | 1 | The cushion of air it lands on: how far it glides, how much it bounces and how far the two hairlines of air open. 0 = it just lands. |
SPEED | script.js | 1 | The speed of everything: 2 is twice as fast, 0.5 half as fast. |
To move between two pages that are each other's flip side: the front and back of a card or an invitation, a product and its spec sheet, the lunch menu and the dinner menu, the two sides of a membership card, a print shop, a stationery shop, a designer's portfolio. It works well between a light page and a dark one.
The same turn with the sizes adapted: the sheet is tall and narrow, the titles shrink to fit the width of the screen and the perspective is worked out on the long side, so the sheet never leaves the stage. A tap on the link turns it over and back.
Nothing lifts and nothing turns: the old page fades out, the new one fades in in its place with the title already at full weight, then the text and the link appear; going back, the same the other way.
GSAP 3.15.0, Newsreader (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 7.3 KB; the libraries: GSAP 28 KB.
Tested on 15 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.