
Lettere in piedi con l'ombra lunga
Testo, Scroll, 3D
NuovaGratis
Scorri dentro l’anteprima
Cinque cartelle che scorrendo si impilano: ognuna si ferma alla stessa altezza, e le linguette, una più in là dell’altra, restano in fila come i divisori di uno schedario. Cliccando una linguetta si torna alla sua cartella.
Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN. Nelle schede React e Vue la stessa demo è già un componente, che spegne le sue animazioni quando esce dalla pagina.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The tabbed folders</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/anybody@5.3.0/wdth.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist-mono@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="top">
<p class="brand">Offcut</p>
<p class="top__line">Selected jobs</p>
</header>
<main>
<section class="intro">
<h1 class="intro__title">Five jobs,<br>filed.</h1>
<p class="intro__text">Every job at Offcut lives in a folder. Scroll, and each one slides over the one before; the tabs stay in a row, so you can always pull a folder back out.</p>
</section>
<!-- every folder sticks at the same height; its tab sits one place further along, so the row fills up -->
<ul class="drawer" data-drawer style="--count: 5">
<li class="folder" data-folder style="--n: 0; --tint: #f7f5ee; --on: #0e1440">
<div class="folder__row"><button class="folder__tab" type="button" data-tab aria-label="Go to Ferry timetable"><span>Ferry</span></button></div>
<article class="folder__body">
<div class="folder__inside">
<div class="folder__text">
<p class="folder__date">March 2026</p>
<h2 class="folder__title">Ferry timetable</h2>
<p class="folder__line">Forty crossings a day, set so you can read them from the pier.</p>
<ul class="folder__tags"><li>Timetable</li><li>Wayfinding</li></ul>
</div>
<figure class="folder__art" aria-hidden="true">
<svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice">
<rect width="400" height="300" fill="#2343e6"/>
<circle cx="306" cy="80" r="38" fill="#ffd21f"/>
<rect x="212" y="112" width="24" height="36" fill="#0e1440"/>
<rect x="212" y="120" width="24" height="8" fill="#ffd21f"/>
<rect x="132" y="146" width="126" height="34" fill="#ff5b4a"/>
<g fill="#f7f5ee"><rect x="146" y="156" width="16" height="13"/><rect x="172" y="156" width="16" height="13"/><rect x="198" y="156" width="16" height="13"/><rect x="224" y="156" width="16" height="13"/></g>
<path d="M84 180 H312 L284 222 H112 Z" fill="#f7f5ee"/>
<path d="M0 228 q25 -16 50 0 t50 0 t50 0 t50 0 t50 0 t50 0 t50 0 t50 0 V300 H0 Z" fill="#1a31b4"/>
<path d="M-25 256 q25 -16 50 0 t50 0 t50 0 t50 0 t50 0 t50 0 t50 0 t50 0 t50 0 V300 H-25 Z" fill="#0e1440"/>
</svg>
<i></i><i></i><i></i><i></i>
</figure>
</div>
</article>
</li>
<li class="folder" data-folder style="--n: 1; --tint: #7df0c4; --on: #0e1440">
<div class="folder__row"><button class="folder__tab" type="button" data-tab aria-label="Go to Seed packets"><span>Seeds</span></button></div>
<article class="folder__body">
<div class="folder__inside">
<div class="folder__text">
<p class="folder__date">January 2026</p>
<h2 class="folder__title">Seed packets</h2>
<p class="folder__line">A packet for every seed in the neighbourhood library, printed in two inks.</p>
<ul class="folder__tags"><li>Packaging</li><li>Riso</li></ul>
</div>
<figure class="folder__art" aria-hidden="true">
<svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice">
<rect width="400" height="300" fill="#f7f5ee"/>
<g transform="rotate(-11 122 156)">
<rect x="70" y="66" width="104" height="172" rx="6" fill="#0e1440"/>
<g transform="translate(122 150)" fill="#7df0c4"><rect x="-3" y="-6" width="6" height="52"/><path d="M0 6 C-30 2 -36 -30 -36 -30 C-8 -32 0 -14 0 6 Z"/><path d="M0 -6 C26 -10 32 -40 32 -40 C8 -40 0 -24 0 -6 Z"/></g>
<rect x="86" y="212" width="72" height="8" fill="#f7f5ee"/>
</g>
<g transform="rotate(3 200 150)">
<rect x="148" y="52" width="104" height="184" rx="6" fill="#ff5b4a"/>
<g transform="translate(200 146)" fill="#0e1440"><rect x="-3" y="-6" width="6" height="56"/><path d="M0 8 C-30 4 -36 -28 -36 -28 C-8 -30 0 -12 0 8 Z"/><path d="M0 -4 C26 -8 32 -38 32 -38 C8 -38 0 -22 0 -4 Z"/></g>
<rect x="164" y="210" width="72" height="8" fill="#f7f5ee"/>
</g>
<g transform="rotate(15 282 160)">
<rect x="230" y="70" width="104" height="172" rx="6" fill="#ffd21f"/>
<g transform="translate(282 154)" fill="#0e1440"><rect x="-3" y="-6" width="6" height="52"/><path d="M0 6 C-30 2 -36 -30 -36 -30 C-8 -32 0 -14 0 6 Z"/><path d="M0 -6 C26 -10 32 -40 32 -40 C8 -40 0 -24 0 -6 Z"/></g>
<rect x="246" y="216" width="72" height="8" fill="#0e1440"/>
</g>
</svg>
<i></i><i></i><i></i><i></i>
</figure>
</div>
</article>
</li>
<li class="folder" data-folder style="--n: 2; --tint: #0e1440; --on: #f7f5ee">
<div class="folder__row"><button class="folder__tab" type="button" data-tab aria-label="Go to Night market"><span>Market</span></button></div>
<article class="folder__body">
<div class="folder__inside">
<div class="folder__text">
<p class="folder__date">October 2025</p>
<h2 class="folder__title">Night market</h2>
<p class="folder__line">Posters that glow under the lamps: one for each of the six nights.</p>
<ul class="folder__tags"><li>Posters</li><li>Screen print</li></ul>
</div>
<figure class="folder__art" aria-hidden="true">
<svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice">
<rect width="400" height="300" fill="#1a31b4"/>
<path d="M318 34 a46 46 0 1 0 34 78 a36 36 0 1 1 -34 -78 Z" fill="#ffd21f"/>
<path d="M0 92 Q200 150 400 80" fill="none" stroke="#f7f5ee" stroke-width="2.5"/>
<g fill="#ffd21f"><rect x="52" y="106" width="16" height="24" rx="5"/><rect x="122" y="120" width="16" height="24" rx="5"/><rect x="192" y="125" width="16" height="24" rx="5"/><rect x="262" y="118" width="16" height="24" rx="5"/></g>
<g>
<rect x="46" y="200" width="7" height="72" fill="#f7f5ee"/><rect x="166" y="200" width="7" height="72" fill="#f7f5ee"/>
<path d="M30 168 H190 L176 204 H44 Z" fill="#ff5b4a"/>
<g fill="#f7f5ee"><path d="M62 168 H94 L90 204 H64 Z"/><path d="M126 168 H158 L156 204 H130 Z"/></g>
<rect x="40" y="244" width="140" height="30" fill="#f7f5ee"/>
</g>
<g>
<rect x="232" y="212" width="7" height="60" fill="#f7f5ee"/><rect x="348" y="212" width="7" height="60" fill="#f7f5ee"/>
<path d="M216 182 H372 L358 216 H230 Z" fill="#7df0c4"/>
<g fill="#0e1440"><path d="M248 182 H278 L274 216 H250 Z"/><path d="M310 182 H340 L338 216 H314 Z"/></g>
<rect x="226" y="250" width="136" height="24" fill="#f7f5ee"/>
</g>
</svg>
<i></i><i></i><i></i><i></i>
</figure>
</div>
</article>
</li>
<li class="folder" data-folder style="--n: 3; --tint: #ffd21f; --on: #0e1440">
<div class="folder__row"><button class="folder__tab" type="button" data-tab aria-label="Go to Paper zoo"><span>Zoo</span></button></div>
<article class="folder__body">
<div class="folder__inside">
<div class="folder__text">
<p class="folder__date">June 2025</p>
<h2 class="folder__title">Paper zoo</h2>
<p class="folder__line">A book to cut up: eleven animals, and not a drop of glue.</p>
<ul class="folder__tags"><li>Book</li><li>Die cut</li></ul>
</div>
<figure class="folder__art" aria-hidden="true">
<svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice">
<rect width="400" height="300" fill="#f7f5ee"/>
<path d="M70 44 H330 V262 H70 Z" fill="none" stroke="#0e1440" stroke-width="2.5" stroke-dasharray="9 8"/>
<path d="M112 74 L200 158 L112 196 Z" fill="#ff5b4a"/>
<path d="M288 74 L200 158 L288 196 Z" fill="#ff5b4a"/>
<path d="M112 196 L200 158 L288 196 L200 248 Z" fill="#e8402f"/>
<path d="M150 204 L200 182 L250 204 L200 248 Z" fill="#f7f5ee" stroke="#0e1440" stroke-width="0"/>
<path d="M186 232 H214 L200 248 Z" fill="#0e1440"/>
<path d="M150 150 l18 10 l-18 8 Z" fill="#0e1440"/>
<path d="M250 150 l-18 10 l18 8 Z" fill="#0e1440"/>
</svg>
<i></i><i></i><i></i><i></i>
</figure>
</div>
</article>
</li>
<li class="folder" data-folder style="--n: 4; --tint: #ff5b4a; --on: #0e1440">
<div class="folder__row"><button class="folder__tab" type="button" data-tab aria-label="Go to Open Tuesday"><span>Tuesday</span></button></div>
<article class="folder__body">
<div class="folder__inside">
<div class="folder__text">
<p class="folder__date">April 2025</p>
<h2 class="folder__title">Open Tuesday</h2>
<p class="folder__line">Signs for a repair café that opens one evening a week.</p>
<ul class="folder__tags"><li>Signage</li><li>Stencil</li></ul>
</div>
<figure class="folder__art" aria-hidden="true">
<svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice">
<rect width="400" height="300" fill="#0e1440"/>
<path d="M136 92 q-14 -16 0 -32 M170 92 q-14 -16 0 -32 M204 92 q-14 -16 0 -32" fill="none" stroke="#f7f5ee" stroke-width="7" stroke-linecap="round"/>
<path d="M226 144 h20 a28 28 0 0 1 0 56 h-20" fill="none" stroke="#f7f5ee" stroke-width="15"/>
<path d="M104 116 H236 V206 a30 30 0 0 1 -30 30 H134 a30 30 0 0 1 -30 -30 Z" fill="#f7f5ee"/>
<g transform="rotate(34 300 176)">
<rect x="289" y="120" width="22" height="132" rx="7" fill="#ffd21f"/>
<circle cx="300" cy="118" r="28" fill="#ffd21f"/>
<rect x="290" y="82" width="20" height="38" fill="#0e1440"/>
</g>
</svg>
<i></i><i></i><i></i><i></i>
</figure>
</div>
</article>
</li>
</ul>
<section class="outro">
<p class="outro__text">Next job: yours.</p>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
<script src="script.js"></script>
</body>
</html>Cambia valori, colori e testi con le manopole e guarda l’animazione rispondere dal vivo. Oppure scrivi tu nel codice. Poi scarica la cartella con le tue modifiche.
62 valori da cambiare
Col connettore di Animorio, Claude Code la prende da qui con tutta la sua guida e la adatta al tuo progetto. Incolla questa richiesta:
Prendi «Le cartelle con le linguette» da Animorio e adattala al mio sitoLe cartelle sono le voci di una lista, una dopo l’altra, ognuna con position: sticky e lo stesso top. Quando una arriva alla riga si ferma; la successiva, che nel codice viene dopo e quindi sta sopra, continua a salire e la copre. Fra una e l’altra c’è un margine di 14vh: è lo scorrimento in cui la cartella si vede intera.
Ogni cartella è una riga con la linguetta e, sotto, il corpo. La linguetta è larga un quinto della cartella e ha un margine sinistro di tanti quinti quanti ne dice --n: 0 per la prima, 4 per l’ultima. Il resto della riga è vuoto, e da lì si vedono le linguette delle cartelle sotto. Il lato inclinato è un triangolo ritagliato con clip-path.
Un elemento sticky deve restare dentro il contenuto di chi lo contiene, margine compreso. Per questo la lista finisce con un tratto vuoto, un ::after alto 36vh: finché quel tratto non è passato tutte le cartelle restano ferme, poi se ne vanno insieme.
Un solo numero legato allo scorrimento con ScrollTrigger: quante cartelle sono arrivate sulla prima, frazioni comprese, da 0 a 4. Da lì, per ogni cartella, quante ne ha sopra: si alza di 7 px per ognuna (la variabile --rise), e mentre la prima di queste le sale sopra il suo contenuto scende al 15% di opacità (--fade). Lo scrub ha 0,4 secondi di ritardo.
Quando il numero passa un intero, la cartella arrivata è quella davanti: la sua linguetta salta di 9 px e ricade con un elastico, le quattro maniglie del disegno crescono una dopo l’altra, e la scritta della linguetta si accende. Il clic su una linguetta calcola dove la sua cartella si ferma (il punto della prima, più tante distanze quante cartelle) e ci porta la pagina, con lo scorrimento morbido del browser.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
--count, --n | index.html | 5, 0-4 | Quante cartelle ci sono e il posto di ognuna nella fila: da cambiare insieme quando ne aggiungi o ne togli una. |
--tint, --on | index.html | #f7f5ee, #0e1440 | Il colore di ogni cartella e quello dei suoi testi. |
--top, --tab, --slant | style.css | 58px, 46px, 22px | Dove si fermano le cartelle, quanto sono alte le linguette e quanto è largo il loro lato inclinato. |
LIFT | script.js | 7 | I pixel di cui una cartella si alza per ogni cartella che le arriva sopra. |
FADE | script.js | 0.85 | Quanto contenuto perde una cartella coperta: 1 lo fa sparire del tutto. |
SCRUB | script.js | 0.4 | I secondi che la pila impiega a raggiungere lo scorrimento. |
.folder margin, .drawer::after | style.css | 14vh, 36vh | Lo scorrimento fra una cartella e l’altra, e quanto la pila resta ferma alla fine. |
Per una lista corta di lavori, casi studio, servizi o capitoli, da tre a sei, dove conta vedere subito quanti sono e poterci tornare: il portfolio di uno studio, l’indice di un rapporto, le tappe di un percorso.
Uguale, con le linguette più strette e le scritte a 11 px; dentro la cartella il disegno va sotto il testo e si prende l’altezza che resta.
Le cartelle si impilano lo stesso, perché è la pagina che scorre, ma non si alzano, il contenuto non sfuma e le linguette non saltano; il clic su una linguetta porta alla cartella senza scorrimento animato.
GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Anybody (font variabile) 5.3.0, Geist Mono (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 6,3 KB; le librerie: GSAP + ScrollTrigger 45 KB.
Provata il 30 settembre 2026
Puoi usarla nei tuoi progetti e in quelli dei tuoi clienti. Non puoi rivenderla né ridistribuirla così com’è. GSAP resta sotto la sua licenza Standard. Licenza completa.
Con l’email e la password del tuo account.
oppure con l’email
Hai fatto l’accesso come .
Con l’account scarichi lo zip di ogni animazione e di ogni pacchetto, gratis.