Anima gli elementi durante lo scorrimento con animazioni con scorrimento

Scopri come utilizzare le sequenze temporali di scorrimento e le sequenze temporali delle visualizzazioni per creare animazioni basate sullo scorrimento in modo dichiarativo.

Animazioni basate sullo scorrimento

Supporto dei browser

  • Chrome: 115.
  • Edge: 115.
  • Firefox: dietro una bandiera.
  • Safari: non supportato.

Origine

Le animazioni basate sullo scorrimento sono uno schema UX comune sul web. Un'animazione basata sullo scorrimento è collegata alla posizione di scorrimento di un contenitore di scorrimento. Ciò significa che, mentre scorri verso l'alto o verso il basso, l'animazione collegata esegue lo scrubbing in avanti o indietro nella risposta diretta. Alcuni esempi sono effetti come immagini di sfondo con parallasse o indicatori di lettura che si muovono mentre scorri.

Un indicatore di lettura posizionato sopra un documento, guidato dallo scorrimento.

Un tipo simile di animazione basata sullo scorrimento è un'animazione collegata alla posizione di un elemento all'interno del relativo contenitore di scorrimento. Così facendo, ad esempio, gli elementi possono scomparire man mano che vengono mostrati.

Le immagini in questa pagina spariscono man mano che vengono visualizzate.

Il modo classico per ottenere questo tipo di effetti è rispondere agli eventi di scorrimento sul thread principale, il che porta a due problemi principali:

  • I browser moderni eseguono lo scorrimento in base a un processo separato e, di conseguenza, inviano gli eventi di scorrimento in modo asincrono.
  • Le animazioni del thread principale sono soggette a jank.

Ciò rende impossibile o molto difficile creare animazioni ad alte prestazioni basate sullo scorrimento e sincronizzate con lo scorrimento.

A partire dalla versione 115 di Chrome è disponibile un nuovo insieme di API e concetti che puoi utilizzare per attivare animazioni dichiarative basate sullo scorrimento: sequenze temporali di scorrimento e visualizzazione di sequenze temporali.

Questi nuovi concetti si integrano con le attuali API Web Animations (WAAPI) e CSS Animations, consentendo loro di ereditare i vantaggi offerti da queste API. Ciò include la possibilità di far funzionare animazioni basate sullo scorrimento dal thread principale. Sì, leggi bene: ora puoi avere animazioni fluide e fluide, guidate dallo scorrimento, che vengono eseguite dal thread principale, con poche righe di codice extra. Cosa c'è di no?

Animazioni sul Web, un breve riepilogo

Animazioni sul web con CSS

Per creare un'animazione in CSS, definisci un insieme di fotogrammi chiave utilizzando la regola at-@keyframes. Collegalo a un elemento utilizzando la proprietà animation-name e imposta un animation-duration per determinare la durata dell'animazione. Sono disponibili altre animation-* strutture in formato esteso (animation-easing-function e animation-fill-mode, solo per citarne alcune), che possono essere combinate nella forma abbreviata animation.

Ad esempio, ecco un'animazione che ingrandisce un elemento sull'asse X cambiandone al contempo il colore di sfondo:

@keyframes scale-up {
  from {
    background-color: red;
    transform: scaleX(0);
  }
  to {
    background-color: darkred;
    transform: scaleX(1);
  }
}

#progressbar {
  animation: 2.5s linear forwards scale-up;
}

Animazioni sul web con JavaScript

In JavaScript, è possibile usare l'API Web Animations per ottenere esattamente lo stesso risultato. Puoi farlo creando nuove istanze Animation e KeyFrameEffect o utilizzando il metodo Element animate() molto più breve.

document.querySelector('#progressbar').animate(
  {
    backgroundColor: ['red', 'darkred'],
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    duration: 2500,
    fill: 'forwards',
    easing: 'linear',
   }
);

Questo risultato visivo dello snippet JavaScript riportato sopra è identico alla versione CSS precedente.

Sequenze temporali dell'animazione

Per impostazione predefinita, un'animazione associata a un elemento viene eseguita nella sequenza temporale del documento. L'ora di origine inizia da 0 quando viene caricata la pagina e inizia a scorrere in avanti man mano che l'orologio avanza. Questa è la sequenza temporale predefinita dell'animazione e, fino a questo momento, era l'unica sequenza temporale dell'animazione a cui avevi accesso.

La specifica delle animazioni basate su scorrimento definisce due nuovi tipi di sequenze temporali che puoi utilizzare:

  • Sequenza temporale dell'avanzamento con scorrimento: una sequenza temporale collegata alla posizione di scorrimento di un contenitore di scorrimento lungo un determinato asse.
  • Visualizza cronologia avanzamento: una sequenza temporale collegata alla posizione relativa di un determinato elemento all'interno del relativo contenitore di scorrimento.

Sequenza temporale dell'avanzamento di scorrimento

Una sequenza temporale dell'avanzamento di scorrimento è una sequenza temporale dell'animazione collegata all'avanzamento nella posizione di scorrimento di un contenitore di scorrimento, detta anche scrollport o scroller, lungo un determinato asse. Converte una posizione in un intervallo di scorrimento in una percentuale di avanzamento.

La posizione di scorrimento iniziale rappresenta l'avanzamento dello 0%, mentre la posizione di fine scorrimento rappresenta l'avanzamento del 100%. Nella visualizzazione seguente, puoi vedere che l'avanzamento passa da 0% a 100% mentre scorri la barra di scorrimento dall'alto verso il basso.

Visualizzazione della sequenza temporale di avanzamento di scorrimento. Mentre scorri verso il basso, il valore dell'avanzamento passa da 0% a 100%.

✨ Fai una prova

La sequenza temporale dell'avanzamento di scorrimento è spesso abbreviata in "Sequenza temporale di scorrimento".

Visualizza cronologia avanzamento

Questo tipo di sequenza temporale è collegata all'avanzamento relativo di un determinato elemento all'interno di un contenitore di scorrimento. Proprio come una sequenza temporale di avanzamento di scorrimento, viene monitorato l'offset di scorrimento di uno scorrimento. A differenza di una sequenza temporale dell'avanzamento di scorrimento, è la posizione relativa di un soggetto all'interno dello scorrimento che determina l'avanzamento.

Questo è in qualche modo paragonabile al funzionamento di IntersectionObserver, che può monitorare la quantità di visibilità di un elemento nello scorrimento. Se l'elemento non è visibile nello scorrimento, non si interseca. Se è visibile all'interno della barra di scorrimento, anche nella parte più piccola, si interseca.

La sequenza temporale dell'avanzamento della visualizzazione inizia dal momento in cui un soggetto inizia a intersecarsi con la barra di scorrimento e termina quando il soggetto smette di intersecarsi con la barra di scorrimento. Nella visualizzazione seguente, puoi vedere che l'avanzamento inizia a contare dallo 0% quando il soggetto entra nel contenitore di scorrimento e raggiunge il 100% nel momento in cui il soggetto esce dal contenitore.

Visualizzazione della sequenza temporale di avanzamento della visualizzazione. L'avanzamento passa da 0% a 100%, poiché il soggetto (riquadro verde) attraversa la barra di scorrimento.

✨ Fai una prova

Una sequenza temporale di avanzamento della visualizzazione è spesso abbreviata in "Visualizza cronologia". È possibile scegliere come target parti specifiche di una sequenza temporale di visualizzazione in base alle dimensioni del soggetto, ma in modo più approfondito in seguito.

Fare pratica con le sequenze temporali dell'avanzamento di scorrimento

Creazione di una sequenza temporale di avanzamento di scorrimento anonima in CSS

Il modo più semplice per creare una sequenza temporale di scorrimento in CSS è utilizzare la funzione scroll(). Viene creata una cronologia di scorrimento anonima che puoi impostare come valore per la nuova proprietà animation-timeline.

Esempio:

@keyframes animate-it {  }

.subject {
  animation: animate-it linear;
  animation-timeline: scroll(root block);
}

La funzione scroll() accetta un argomento <scroller> e un argomento <axis>.

I valori accettati per l'argomento <scroller> sono i seguenti:

  • nearest: utilizza il container di scorrimento del predecessore più vicino (predefinito).
  • root: utilizza l'area visibile del documento come contenitore di scorrimento.
  • self: utilizza l'elemento stesso come contenitore di scorrimento.

I valori accettati per l'argomento <axis> sono i seguenti:

  • block: utilizza la misura dell'avanzamento lungo l'asse del blocco del contenitore di scorrimento (impostazione predefinita).
  • inline: utilizza la misura dell'avanzamento lungo l'asse in linea del contenitore di scorrimento.
  • y: utilizza la misurazione dell'avanzamento lungo l'asse Y del contenitore di scorrimento.
  • x: utilizza la misura dell'avanzamento lungo l'asse X del contenitore di scorrimento.

Ad esempio, per associare un'animazione allo scorrimento principale sull'asse del blocco, i valori da passare in scroll() sono root e block. Complessivamente, il valore è scroll(root block).

Demo: indicatore di avanzamento nella lettura

Questa demo ha un indicatore di avanzamento della lettura fisso nella parte superiore dell'area visibile. Mentre scorri la pagina verso il basso, la barra di avanzamento cresce fino a occupare l'intera larghezza dell'area visibile quando raggiungi la fine del documento. Per guidare l'animazione, viene utilizzata una cronologia di avanzamento dello scorrimento anonima.

Demo: Indicatore di avanzamento della lettura.

✨ Fai una prova

L'indicatore di avanzamento della lettura viene posizionato nella parte superiore della pagina utilizzando la posizione fissa. Per sfruttare le animazioni composte, l'elemento width non viene animato, ma viene ridotto l'elemento sull'asse x utilizzando un transform.

<body>
  <div id="progress"></div>
  …
</body>
@keyframes grow-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

#progress {
  position: fixed;
  left: 0; top: 0;
  width: 100%; height: 1em;
  background: red;

  transform-origin: 0 50%;
  animation: grow-progress auto linear;
  animation-timeline: scroll();
}

La sequenza temporale dell'animazione grow-progress nell'elemento #progress è impostata su una sequenza temporale anonima creata utilizzando scroll(). Non vengono forniti argomenti, quindi scroll() ricorrerà ai valori predefiniti.

Lo scorrimento predefinito da monitorare è nearest e l'asse predefinito è block. In questo modo, viene scelto come target lo scorrimento principale in quanto è lo scorrimento più vicino dell'elemento #progress, monitorando la direzione del blocco.

Creazione di una sequenza temporale dell'avanzamento di scorrimento denominata in CSS

Un modo alternativo per definire una sequenza temporale dell'avanzamento di scorrimento è utilizzarne una denominata. È un po' più dettagliato, ma può tornare utile quando non hai scelto come target un dispositivo di scorrimento principale o uno di scorrimento principale oppure se la pagina utilizza più sequenze temporali o quando le ricerche automatiche non funzionano. In questo modo, puoi identificare una sequenza temporale dell'avanzamento di scorrimento dal nome che le assegni.

Per creare una sequenza temporale dell'avanzamento di scorrimento denominata su un elemento, imposta la proprietà CSS scroll-timeline-name nel contenitore di scorrimento su un identificatore di tua preferenza. Il valore deve iniziare con --.

Per modificare l'asse da monitorare, dichiara anche la proprietà scroll-timeline-axis. I valori consentiti sono uguali all'argomento <axis> di scroll().

Infine, per collegare l'animazione alla sequenza temporale dell'avanzamento di scorrimento, imposta la proprietà animation-timeline nell'elemento che deve essere animato sullo stesso valore dell'identificatore utilizzato per scroll-timeline-name.

Esempio di codice:

@keyframes animate-it {  }

.scroller {
  scroll-timeline-name: --my-scroller;
  scroll-timeline-axis: inline;
}

.scroller .subject {
  animation: animate-it linear;
  animation-timeline: --my-scroller;
}

Se necessario, puoi combinare scroll-timeline-name e scroll-timeline-axis nella forma abbreviata scroll-timeline. Ad esempio:

scroll-timeline: --my-scroller inline;

Questa demo presenta un indicatore dei passaggi mostrato sopra ogni carosello di immagini. Quando un carosello contiene tre immagini, la barra dell'indicatore inizia con una larghezza al 33% per indicare che si sta visualizzando l'immagine una di tre. Quando è visualizzata l'ultima immagine, determinata dallo scorrimento fino alla fine, l'indicatore occupa l'intera larghezza della barra di scorrimento. Per guidare l'animazione viene utilizzata una sequenza temporale di avanzamento dello scorrimento denominata.

Demo: Indicatore dei passaggi del carosello orizzontale.

✨ Fai una prova

Il markup di base per una galleria è il seguente:

<div class="gallery" style="--num-images: 2;">
  <div class="gallery__scrollcontainer">
    <div class="gallery__progress"></div>
    <div class="gallery__entry">…</div>
    <div class="gallery__entry">…</div>
  </div>
</div>

L'elemento .gallery__progress è assolutamente posizionato all'interno dell'elemento wrapper .gallery. La sua dimensione iniziale è determinata dalla proprietà personalizzata --num-images.

.gallery {
  position: relative;
}


.gallery__progress {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 1em;
  transform: scaleX(calc(1 / var(--num-images)));
}

.gallery__scrollcontainer dispone orizzontalmente gli elementi .gallery__entry contenuti ed è l'elemento che scorre. Monitorando la posizione di scorrimento, .gallery__progress viene animato. Per farlo, fai riferimento alla cronologia dell'avanzamento di scorrimento denominata --gallery__scrollcontainer.

@keyframes grow-progress {
  to { transform: scaleX(1); }
}

.gallery__scrollcontainer {
  overflow-x: scroll;
  scroll-timeline: --gallery__scrollcontainer inline;
}
.gallery__progress {
  animation: auto grow-progress linear forwards;
  animation-timeline: --gallery__scrollcontainer;
}

Creazione di una sequenza temporale dell'avanzamento di scorrimento con JavaScript

Per creare una sequenza temporale di scorrimento in JavaScript, crea una nuova istanza della classe ScrollTimeline. Inserisci un bagaglio della proprietà con il source e il axis che vuoi monitorare.

  • source: un riferimento all'elemento di cui vuoi monitorare lo scorrimento. Utilizza document.documentElement per scegliere come target lo scorrimento principale.
  • axis: determina quale asse monitorare. Analogamente alla variante CSS, i valori accettati sono block, inline, x e y.
const tl = new ScrollTimeline({
  source: document.documentElement,
});

Per allegarlo a un'animazione web, trasmettilo come proprietà timeline e ometti eventuali duration.

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
});

Demo: indicatore di avanzamento nella lettura, rivisto

Per ricreare l'indicatore di avanzamento nella lettura con JavaScript, usando lo stesso markup, utilizza il seguente codice JavaScript:

const $progressbar = document.querySelector('#progress');

$progressbar.style.transformOrigin = '0% 50%';
$progressbar.animate(
  {
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    fill: 'forwards',
    timeline: new ScrollTimeline({
      source: document.documentElement,
    }),
  }
);

Il risultato visivo è identico nella versione CSS: lo strumento timeline creato tiene traccia dello scorrimento delle radici e aumenta #progress sull'asse x da 0% a 100% mentre scorri la pagina.

✨ Fai una prova

Fare pratica con la visualizzazione della cronologia dei progressi

Creazione di una sequenza temporale dell'avanzamento di una visualizzazione anonima in CSS

Per creare una visualizzazione della cronologia dell'avanzamento, utilizza la funzione view(). I relativi argomenti accettati sono <axis> e <view-timeline-inset>.

  • Il <axis> è lo stesso della sequenza temporale dell'avanzamento di scorrimento e definisce l'asse da monitorare. Il valore predefinito è block.
  • Con <view-timeline-inset>, puoi specificare un offset (positivo o negativo) per regolare i limiti quando un elemento è considerato visibile o meno. Il valore deve essere una percentuale o auto, dove auto è il valore predefinito.

Ad esempio, per associare un'animazione a un elemento che si interseca con il relativo cursore sull'asse del blocco, utilizza view(block). Analogamente a scroll(), imposta questo come valore per la proprietà animation-timeline e non dimenticare di impostare animation-duration su auto.

Con il seguente codice, ogni img verrà dissolvenza in entrata attraversando l'area visibile mentre scorri.

@keyframes reveal {
  from { opacity: 0; }
  to { opacity: 1; }
}

img {
  animation: reveal linear;
  animation-timeline: view();
}

Intermezzo: visualizzare gli intervalli di Spostamenti

Per impostazione predefinita, un'animazione collegata alla sequenza temporale della visualizzazione viene associata all'intero intervallo della sequenza temporale. L'azione inizia dal momento in cui il soggetto sta per entrare nell'area di scorrimento e termina quando il soggetto ha lasciato completamente l'area di scorrimento.

È anche possibile collegarlo a una parte specifica della visualizzazione cronologica specificando l'intervallo a cui deve associarlo. Ad esempio, questo può avvenire solo quando il soggetto sta entrando nella barra di scorrimento. Nella visualizzazione seguente, l'avanzamento inizia il conteggio dallo 0% quando il soggetto entra nel contenitore di scorrimento, ma raggiunge già il 100% dal momento in cui si interseca completamente.

Una visualizzazione della sequenza temporale impostata per tenere traccia dell'intervallo di ingresso del soggetto. L'animazione viene eseguita solo mentre il soggetto entra nell'area di scorrimento.

I possibili intervalli di Spostamenti di Visualizza che puoi scegliere come target sono i seguenti:

  • cover: rappresenta l'intero intervallo della sequenza temporale di avanzamento della visualizzazione.
  • entry: rappresenta l'intervallo durante il quale la casella dell'entità entra nell'intervallo di visibilità dell'avanzamento della visualizzazione.
  • exit: rappresenta l'intervallo durante il quale la casella dell'entità esce dall'intervallo di visibilità dell'avanzamento della visualizzazione.
  • entry-crossing: rappresenta l'intervallo durante il quale la casella principale supera il bordo del bordo finale.
  • exit-crossing: rappresenta l'intervallo durante il quale la casella principale attraversa il bordo del bordo iniziale.
  • contain: rappresenta l'intervallo durante il quale la casella dell'entità è contenuta per intero o copre completamente l'intervallo di visibilità dell'avanzamento della visualizzazione all'interno dell'area di scorrimento. Dipende dal fatto che il soggetto sia più alto o più corto dell'autore dello scorrimento.

Per definire un intervallo, devi impostare i valori di inizio e fine intervallo. Ciascuno è costituito da un nome-intervallo (vedi l'elenco sopra) e da un offset di intervallo per determinare la posizione all'interno di quel nome-intervallo. L'offset dell'intervallo è in genere una percentuale che va da 0% a 100%, ma puoi anche specificare una lunghezza fissa, ad esempio 20em.

Ad esempio, se vuoi eseguire un'animazione dal momento in cui entra un soggetto, scegli entry 0% come inizio dell'intervallo. Per farlo terminare prima di inserire il soggetto, scegli entry 100% come valore per la fine dell'intervallo.

In CSS, puoi impostare questo valore utilizzando la proprietà animation-range. Esempio:

animation-range: entry 0% entry 100%;

In JavaScript, utilizza le proprietà rangeStart e rangeEnd.

$el.animate(
  keyframes,
  {
    timeline: tl,
    rangeStart: 'entry 0%',
    rangeEnd: 'entry 100%',
  }
);

Utilizza lo strumento incorporato di seguito per vedere cosa rappresenta ogni nome-intervallo e come le percentuali influiscono sulle posizioni iniziali e finali. Prova a impostare l'inizio dell'intervallo su entry 0% e la fine dell'intervallo su cover 50%, quindi trascina la barra di scorrimento per vedere il risultato dell'animazione.

Il visualizzatore degli intervalli della cronologia delle visualizzazioni, disponibile all'indirizzo https://goo.gle/view-timeline-range-tool

Guardare una registrazione

Come puoi notare, mentre giochi con gli strumenti Visualizza intervalli sequenza temporale, alcuni intervalli possono essere scelti come target da due diverse combinazioni nome-intervallo + offset intervallo. Ad esempio, entry 0%, entry-crossing 0% e cover 0% hanno tutti come target la stessa area.

Quando i valori di inizio e fine intervallo hanno come target lo stesso nome dell'intervallo e coprono l'intero intervallo, da 0% a 100%, puoi accorciare il valore in modo che sia semplicemente il nome dell'intervallo. Ad esempio, animation-range: entry 0% entry 100%; può essere riscritto nel formato animation-range: entry molto più breve.

Demo: rivelazione delle immagini

Questa demo si dissolve nelle immagini man mano che entrano nell'area di scorrimento. Per farlo, usa una sequenza temporale di visualizzazione anonima. L'intervallo dell'animazione è stato modificato in modo che ogni immagine sia completamente opaca quando si trova a metà dello scorrimento.

Demo: Rivelazione immagini

✨ Fai una prova

L'effetto di espansione si ottiene utilizzando un percorso di clip animato. Il CSS utilizzato per questo effetto è il seguente:

@keyframes reveal {
  from { opacity: 0; clip-path: inset(0% 60% 0% 50%); }
  to { opacity: 1; clip-path: inset(0% 0% 0% 0%); }
}

.revealing-image {
  animation: auto linear reveal both;
  animation-timeline: view();
  animation-range: entry 25% cover 50%;
}

Creazione di una sequenza temporale denominata Visualizza avanzamento in CSS

Analogamente a come le sequenze temporali di scorrimento hanno nomi di versioni, puoi anche creare sequenze temporali denominate Visualizza sequenze temporali. Al posto delle proprietà scroll-timeline-*, utilizzi varianti che includono il prefisso view-timeline-, ovvero view-timeline-name e view-timeline-axis.

Vengono applicati gli stessi tipi di valori e le stesse regole per la ricerca di una sequenza temporale denominata.

Demo: rivelazione delle immagini, rivisitata

Rielaborando la demo sull'immagine mostrata in precedenza, il codice rivisto ha il seguente aspetto:

.revealing-image {
  view-timeline-name: --revealing-image;
  view-timeline-axis: block;

  animation: auto linear reveal both;
  animation-timeline: --revealing-image;
  animation-range: entry 25% cover 50%;
}

Utilizzando view-timeline-name: revealing-image, l'elemento verrà monitorato all'interno dello scorrimento più vicino. Lo stesso valore viene quindi utilizzato come valore per la proprietà animation-timeline. L'output visivo è esattamente lo stesso di prima.

✨ Fai una prova

Creazione di una sequenza temporale dell'avanzamento della visualizzazione in JavaScript

Per creare una visualizzazione degli Spostamenti in JavaScript, crea una nuova istanza della classe ViewTimeline. Pass in un bagaglio della proprietà con il subject che vuoi monitorare, axis e inset.

  • subject: un riferimento all'elemento che vuoi monitorare all'interno del suo dispositivo di scorrimento.
  • axis: l'asse da monitorare. Analogamente alla variante CSS, i valori accettati sono block, inline, x e y.
  • inset: una regolazione (positiva) o iniziale (negativa) dell'area di scorrimento per determinare se il riquadro è visibile.
const tl = new ViewTimeline({
  subject: document.getElementById('subject'),
});

Per allegarlo a un'animazione web, trasmettilo come proprietà timeline e ometti eventuali duration. Facoltativamente, trasmetti le informazioni sull'intervallo utilizzando le proprietà rangeStart e rangeEnd.

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
  rangeStart: 'entry 25%',
  rangeEnd: 'cover 50%',
});

✨ Fai una prova

Altre cose da provare

Collegamento a più intervalli della sequenza temporale di visualizzazione con un set di fotogrammi chiave

Vediamo questa demo sugli elenchi di contatti in cui le voci dell'elenco sono animate. Quando una voce di elenco entra in una finestra di scorrimento dal basso, l'area di scorrimento diventa dissolvenza in entrata e, quando esce dall'area di scorrimento in alto, l'area di scorrimento si dissolve in uscita.

Demo: Elenco contatti

✨ Fai una prova

Per questa demo, ogni elemento viene decorato con una sequenza temporale delle visualizzazioni che tiene traccia dell'elemento mentre attraversa la relativa area di scorrimento, ma vi sono collegate due animazioni basate sullo scorrimento. L'animazione animate-in è collegata all'intervallo entry della sequenza temporale e l'animazione animate-out all'intervallo exit della sequenza temporale.

@keyframes animate-in {
  0% { opacity: 0; transform: translateY(100%); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes animate-out {
  0% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-100%); }
}

#list-view li {
  animation: animate-in linear forwards,
             animate-out linear forwards;
  animation-timeline: view();
  animation-range: entry, exit;
}

Invece di eseguire due animazioni diverse associate a due intervalli diversi, è anche possibile creare un set di fotogrammi chiave che contiene già le informazioni sull'intervallo.

@keyframes animate-in-and-out {
  entry 0%  {
    opacity: 0; transform: translateY(100%);
  }
  entry 100%  {
    opacity: 1; transform: translateY(0);
  }
  exit 0% {
    opacity: 1; transform: translateY(0);
  }
  exit 100% {
    opacity: 0; transform: translateY(-100%);
  }
}

#list-view li {
  animation: linear animate-in-and-out;
  animation-timeline: view();
}

Poiché i fotogrammi chiave contengono informazioni sull'intervallo, non è necessario specificare il valore animation-range. Il risultato è esattamente lo stesso di prima.

✨ Fai una prova

Collegamento a una sequenza temporale di scorrimento non predecessore

Il meccanismo di ricerca per le sequenze temporali di scorrimento denominate e per le sequenze temporali denominate è limitato solo ai predecessori di scorrimento. Molto spesso, però, l'elemento che deve essere animato non è un elemento secondario dello scorrimento da tracciare.

Affinché funzioni, entra in gioco la proprietà timeline-scope. Questa proprietà viene utilizzata per dichiarare una sequenza temporale con quel nome senza crearla effettivamente. In questo modo la sequenza temporale con questo nome avrà un ambito più ampio. In pratica, si utilizza la proprietà timeline-scope su un elemento principale condiviso in modo che la sequenza temporale di uno scorrimento secondario possa essere collegata.

Ad esempio:

.parent {
  timeline-scope: --tl;
}
.parent .scroller {
  scroll-timeline: --tl;
}
.parent .scroller ~ .subject {
  animation: animate linear;
  animation-timeline: --tl;
}

In questo snippet:

  • L'elemento .parent dichiara una sequenza temporale con il nome --tl. Qualsiasi elemento secondario può trovarlo e utilizzarlo come valore per la proprietà animation-timeline.
  • L'elemento .scroller in realtà definisce una sequenza temporale di scorrimento con il nome --tl. Per impostazione predefinita, sarà visibile solo agli elementi secondari, ma poiché in .parent è impostato come scroll-timeline-root, viene associato.
  • L'elemento .subject utilizza la sequenza temporale --tl. Cammina verso l'albero dei suoi predecessori e trova --tl sul .parent. Con il --tl su .parent che rimanda al --tl del .scroller, .subject in pratica monitorerà la sequenza temporale dell'avanzamento di scorrimento di .scroller.

In altre parole, puoi utilizzare timeline-root per spostare una sequenza temporale fino a un predecessore (ovvero sollevamento), in modo che tutti i relativi figli secondari possano accedervi.

La proprietà timeline-scope può essere utilizzata sia con le sequenze temporali di scorrimento sia con le visualizzazioni degli Spostamenti.

Altre demo e risorse

Tutte le demo trattate in questo articolo sul mini-sito scroll-driven-animations.style. Il sito web include molte altre demo per mettere in evidenza le possibilità offerte dalle animazioni basate su scorrimento.

Una delle demo aggiuntive è quella di questo elenco di cover dell'album. Ogni copertina ruota in 3D mentre prende il centro dell'area in evidenza.

Demo: Flusso di copertina

✨ Fai una prova

Oppure questa demo di schede sovrapposte che usano position: sticky. Man mano che le carte si accumulano, le carte già bloccate si ridimensionano, creando un piacevole effetto di profondità. Alla fine, l'intera pila scompare dalla visualizzazione come gruppo.

Demo: Sovrapposizione di schede.

✨ Fai una prova

Inoltre, su scroll-driven-animations.style è presente una raccolta di strumenti come la visualizzazione dell'avanzamento dell'intervallo della sequenza temporale, inclusa in precedenza in questo post.

Le animazioni basate sullo scorrimento sono trattate anche nella pagina Novità delle animazioni web al Google I/O '23.