
Lettere in piedi con l'ombra lunga
Testo, Scroll, 3D
NuovaGratis
Scorrendo, ogni titolo arriva sfocato e viene a fuoco nel primo quarto della corsa; poi sale piano mentre il sottotitolo lo supera più veloce.
Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN.
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Titoli che vengono a fuoco</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<section class="apertura">
<p class="sopra">Scorri piano</p>
<p class="grande">I titoli arrivano sfocati e vengono a fuoco mentre scorri; poi salgono, e il sottotitolo li supera.</p>
</section>
<section class="capitolo" data-fuoco>
<h2 class="titolo">Tutto parte<br>da una curva</h2>
<p class="sottotitolo">Prima si decide come parte e come frena. Il resto viene dopo.</p>
</section>
<section class="citazione" data-citazione>
<blockquote>«Un’animazione che arriva dritta sembra spinta. Una che frena sembra viva.»</blockquote>
</section>
<section class="capitolo" data-fuoco>
<h2 class="titolo">Il tempo è<br>un materiale</h2>
<p class="sottotitolo">Si taglia, si allunga, si piega: come il legno, ha una venatura.</p>
</section>
<section class="capitolo" data-fuoco>
<h2 class="titolo">Il resto<br>è ritmo</h2>
<p class="sottotitolo">Fine. Torna su e rifallo.</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>/* Titoli che vengono a fuoco */
:root {
--fondo: #f6f7f3;
--inchiostro: #07201f;
--tenue: #5b706d;
}
* { box-sizing: border-box; }
html,
body {
margin: 0;
}
body {
font-family: 'Mona Sans Variable', system-ui, sans-serif;
color: var(--inchiostro);
background: var(--fondo);
overflow-x: clip;
}
.sopra {
margin: 0 0 12px;
font-size: 14px;
font-weight: 620;
color: var(--tenue);
}
.grande {
margin: 0;
max-width: 26ch;
font-size: clamp(24px, 3vw, 44px);
font-weight: 620;
line-height: 1.06;
letter-spacing: -0.03em;
}
.apertura {
min-height: 80vh;
padding: 12vh clamp(18px, 5vw, 72px);
display: flex;
flex-direction: column;
justify-content: flex-end;
}
/* ogni capitolo è alto uno schermo e mezzo: il titolo ha il tempo di mettere a fuoco e salire */
.capitolo {
min-height: 150vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 28px;
padding: 0 clamp(18px, 5vw, 72px);
text-align: center;
}
.titolo {
margin: 0;
font-size: clamp(56px, 11vw, 190px);
font-weight: 820;
font-stretch: 75%;
line-height: 0.86;
letter-spacing: -0.02em;
text-transform: uppercase;
will-change: transform, filter, opacity;
}
.sottotitolo {
max-width: 32ch;
margin: 0;
font-size: clamp(15px, 1.3vw, 19px);
line-height: 1.45;
color: var(--tenue);
will-change: transform;
}
.citazione {
min-height: 110vh;
display: grid;
place-items: center;
padding: 0 clamp(18px, 8vw, 140px);
}
blockquote {
margin: 0;
max-width: 24ch;
font-size: clamp(28px, 4vw, 60px);
font-weight: 300;
font-stretch: 118%;
line-height: 1.15;
letter-spacing: -0.02em;
text-align: center;
will-change: filter, opacity;
}/* Titoli che vengono a fuoco
Ogni titolo è legato allo scorrimento del suo capitolo. All'ingresso è sfocato, semitrasparente e più
in basso; entro il primo quarto della corsa arriva a fuoco. Poi sale piano mentre il sottotitolo sale
molto più in fretta e lo supera: due velocità diverse danno profondità senza nessun 3D. Le citazioni
fanno solo la messa a fuoco, un po' più lenta. */
gsap.registerPlugin(ScrollTrigger);
/* ---- valori da cambiare ---- */
const SFOCATO = 14; /* pixel di sfocatura all'ingresso del titolo */
const A_FUOCO = 0.24; /* a che punto della corsa il titolo è nitido */
const SU_TITOLO = -30; /* di quanto sale il titolo alla fine, in percentuale della sua altezza */
const SU_SOTTO = -150; /* di quanto sale il sottotitolo: di più, quindi più veloce */
const RIDOTTO = matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!RIDOTTO) {
document.querySelectorAll('[data-fuoco]').forEach((cap) => {
const titolo = cap.querySelector('.titolo');
const sotto = cap.querySelector('.sottotitolo');
gsap.timeline({
defaults: { ease: 'none' },
scrollTrigger: { trigger: cap, start: 'top bottom', end: 'bottom top', scrub: 0.8 },
})
.fromTo(titolo, { filter: `blur(${SFOCATO}px)`, opacity: 0.35, yPercent: 50 },
{ filter: 'blur(0px)', opacity: 1, yPercent: 0, duration: A_FUOCO, ease: 'power2.out' }, 0)
.fromTo(sotto, { yPercent: 60, opacity: 0 }, { yPercent: 0, opacity: 1, duration: A_FUOCO, ease: 'power2.out' }, 0.05)
.to(titolo, { yPercent: SU_TITOLO, duration: 1 - A_FUOCO }, A_FUOCO)
.to(sotto, { yPercent: SU_SOTTO, duration: 1 - A_FUOCO }, A_FUOCO);
});
document.querySelectorAll('[data-citazione] blockquote').forEach((q) => {
gsap.fromTo(q, { filter: 'blur(8px)', opacity: 0.35 }, {
filter: 'blur(0px)', opacity: 1, ease: 'power1.out',
scrollTrigger: { trigger: q, start: 'top bottom', end: 'top 45%', scrub: 0.8 },
});
});
}Ogni capitolo ha la sua timeline con scrub, dall’ingresso dal basso all’uscita in alto. Dentro, le durate sono frazioni della corsa: la messa a fuoco dura 0,24, cioè un quarto.
Il titolo va da blur(14px), opacità 0,35 e yPercent 50 a nitido, pieno e al suo posto, con power2.out: arriva deciso e poi si posa.
Nel resto della corsa il titolo sale del 30% della sua altezza, il sottotitolo del 150%: stessa durata, strade diverse, quindi il sottotitolo va più veloce e lo supera. È una parallasse senza immagini.
Le citazioni fanno solo il fuoco, da blur(8px) a nitide, fra l’ingresso e poco oltre la metà dello schermo: non si muovono, per farle leggere.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
SFOCATO | script.js | 14 | I pixel di sfocatura all’ingresso. |
A_FUOCO | script.js | 0.24 | A che punto della corsa il titolo è nitido. |
SU_TITOLO / SU_SOTTO | script.js | -30 / -150 | Quanto salgono titolo e sottotitolo dopo la messa a fuoco. |
Per le aperture dei capitoli di una pagina lunga: rapporti, storie, manifesti. Non per i testi da leggere di seguito: un paragrafo sfocato è un paragrafo che non si legge.
Identico. Il filtro blur su testi enormi pesa: tienilo solo sui titoli.
Titoli e citazioni sono nitidi e fermi.
GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Mona Sans (font variabile) 5.3.0.
Peso: 5,2 KB dei nostri file.
Provata il 27 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.
Hai fatto l’accesso come .
Il tuo piano è gratis. Quando arriverà, l’accesso a vita si attiverà su questo stesso account.