29 settembre 2026
Effetti di entrata e uscita guidati dallo scroll: un approccio moderno, robusto e accessibile
Separare entry/exit con Scroll-Driven Animations, fare feature detection e prevedere un fallback pulito con Intersection Observer.
Implementare animazioni legate allo scroll è facile… farle bene (senza calcoli fragili e senza rompere layout e accessibilità) un po’ meno. Vediamo un’impostazione moderna: due animazioni separate per entrata e uscita, legate a range dedicati della scroll timeline, con feature detection e fallback via Intersection Observer.
Le animazioni “scroll-driven” sono una delle evoluzioni più interessanti del frontend moderno: permettono di legare l’avanzamento di un’animazione allo scorrimento, ottenendo transizioni fluide e controllabili.
Il problema è che molte implementazioni “classiche” finiscono per dipendere da calcoli percentuali e assunzioni rigide su dimensioni e proporzioni (altezza della card vs viewport, offset fissi, soglie che cambiano al variare del contenuto). Il risultato tipico: animazioni che quasi funzionano, ma si spezzano su schermi diversi, con contenuti dinamici o quando cambiano i breakpoint.
Qui sotto trovi un approccio più moderno e resistente, centrato su tre idee: separare entrata e uscita, ancorare l’animazione a range semantici di scroll, e fare feature detection con fallback.
1) Il classico anti-pattern: un’unica animazione “tutto-in-uno”
Un errore comune è gestire entrata e uscita nello stesso blocco di keyframes, con progress calcolato “a mano” (spesso in percentuale) basandosi su una relazione fissa tra elemento e viewport.
Perché è fragile:
- Dipende dalla geometria: se l’altezza della card cambia (testi più lunghi, immagini responsive, font diversi), il timing percepito cambia.
- Dipende dalla viewport: su mobile o su display grandi le soglie si spostano e l’effetto può “scattare” o non attivarsi correttamente.
- Mescola fasi diverse: entrata e uscita sono due momenti distinti; forzarli in un’unica curva rende difficile controllare easing, ritardi e stati intermedi.
La sensazione finale può sembrare simile in condizioni ideali, ma basta poco per ottenere misfire o effetti visivamente incoerenti.
2) Pattern moderno: keyframes separati per entry e exit
Un’impostazione più robusta parte da una scelta semplice: due animazioni, due responsabilità.
- Animazione di entrata (es.
slide-in): gestisce il momento in cui l’elemento entra nella zona visibile. - Animazione di uscita (es.
slide-out): gestisce il momento in cui l’elemento lascia la zona visibile.
Questo consente di:
- controllare easing e trasformazioni in modo indipendente;
- evitare compromessi su un’unica curva “universale”;
- ridurre la probabilità di “rimbalzi” o stati intermedi strani.
3) Scroll-Driven Animations con animation-timeline: view() e animation-range
Il salto di qualità arriva quando le animazioni non sono più agganciate a calcoli manuali, ma a concetti nativi: timeline di vista e range di animazione.
L’idea è:
- definire i keyframes (entry/exit);
- associare ciascun keyframe a un range: ad esempio solo durante l’entrata o solo durante l’uscita.
In pratica, invece di dire “quando lo scroll è al 37% fai X”, dici “quando l’elemento sta entrando, anima così; quando sta uscendo, anima cosà”.
Vantaggi principali:
- Resilienza del layout: niente ipotesi rigide su altezze e proporzioni.
- Meno bug al cambio dimensioni: se cambia viewport o contenuto, il range segue la realtà geometrica.
- Migliore leggibilità del CSS: entry e exit diventano intenzioni dichiarative, non matematica di compensazione.
4) Feature detection: progressivo, non “all or nothing”
Scroll-Driven Animations è una feature moderna: non sempre è disponibile ovunque.
Per questo è importante fare feature detection delle proprietà chiave (come animation-timeline: view() e l’uso di animation-range per entry/exit) e applicare la versione avanzata solo quando supportata.
Quando non lo è, non si deve “rinunciare” all’effetto in modo brutale: si passa a un comportamento equivalente o dignitoso.
5) Fallback pragmatico: Intersection Observer
Quando le proprietà scroll-driven non sono supportate, un fallback solido è l’Intersection Observer API.
Non replica al 100% la finezza di una timeline di scroll (non hai la stessa continuità di progress), ma è ottimo per:
- attivare l’animazione di entrata quando l’elemento entra in viewport;
- attivare l’animazione di uscita quando l’elemento esce;
- mantenere performance buone (rispetto a scroll listener manuali) e una logica prevedibile.
Il punto chiave è mantenere l’architettura: entry e exit restano separate anche nel fallback.
6) Accessibilità e qualità percepita
Quando si lavora con animazioni legate allo scroll, “fluido” non significa automaticamente “accessibile”. Due attenzioni pratiche:
- Preferenze utente: prevedi una strategia per chi ha
prefers-reduced-motionattivo (riduci ampiezza, elimina trasformazioni invasive o disattiva l’effetto). - Stati coerenti: assicurati che l’elemento abbia uno stato sensato anche senza animazione (niente contenuti invisibili o posizionamenti strani se l’animazione non parte).
Sintesi operativa
Un’implementazione moderna di effetti di entrata/uscita guidati dallo scroll si regge su pochi pilastri:
- Decoupling: due keyframes distinti (entry e exit), niente “animazione unica per tutto”.
- Range dichiarativi: usa
animation-timeline: view()e associa ogni animazione al suoanimation-range(entrata/uscita). - Feature detection: abilita la versione avanzata solo quando disponibile.
- Fallback pulito: in assenza di supporto, usa Intersection Observer per gestire entrata/uscita senza scroll math fragile.
Il risultato è un effetto che può anche sembrare simile in una demo, ma in produzione fa la differenza: non si rompe quando cambiano dimensioni, contenuto o device, e mantiene un comportamento coerente e manutenibile nel tempo.