Il movimento è una parte fondamentale di qualsiasi esperienza digitale e guida l'utente da un'interazione all'altra. Tuttavia, ci sono alcune lacune nelle animazioni fluide sulla piattaforma web. Queste includono la possibilità di animare facilmente le animazioni di ingresso e uscita e di animare facilmente da e verso il livello superiore per elementi ignorabili come finestre di dialogo e popover.
Per colmare queste lacune, Chrome 116 e 117 includono quattro nuove funzionalità della piattaforma web, che consentono animazioni e transizioni fluide per proprietà discrete.
Queste quattro nuove funzionalità includono:
- La possibilità di animare
display
econtent-visibility
sulla sequenza temporale di un fotogramma chiave (da Chrome 116). - La proprietà
transition-behavior
con la parola chiaveallow-discrete
per consentire le transizioni di proprietà discrete comedisplay
(da Chrome 117). - La regola
@starting-style
per animare gli effetti di ingresso dadisplay: none
e nel livello superiore (da Chrome 117). - La proprietà
overlay
per controllare il comportamento del livello superiore durante un'animazione (da Chrome 117).
Visualizza animazioni nei fotogrammi chiave
In Chrome 116, puoi utilizzare display
e content-visibility
nelle regole per i fotogrammi chiave. Queste verranno scambiate nel momento in cui si trova il fotogramma chiave. Non sono necessari nuovi valori aggiuntivi a supporto:
.card {
animation: fade-out 0.5s forwards;
}
@keyframes fade-out {
100% {
opacity: 0;
display: none;
}
}
L'esempio precedente anima l'opacità su 0 per una durata di 0,5 secondi e poi imposta la visualizzazione su nessuno. Inoltre, la parola chiave forwards
garantisce che l'animazione rimanga allo stato finale, in modo che l'elemento a cui viene applicata rimanga display: none
e opacity: 0
.
Questo è un semplice esempio che riproduce ciò che puoi fare con una transizione (vedi la demo nella sezione dedicata alla transizione). Le transizioni, tuttavia, non sono in grado di creare animazioni più complesse, come nell'esempio seguente:
.card {
animation: spin-and-delete 1s ease-in forwards;
}
@keyframes spin-and-delete {
0% {
transform: rotateY(0);
filter: hue-rotate(0);
}
80% {
transform: rotateY(360deg);
filter: hue-rotate(180deg);
opacity: 1;
}
100% {
opacity: 0;
display: none;
}
}
L'animazione spin-and-delete
è un'animazione di uscita. Per prima cosa, la scheda ruoterà sull'asse Y, passerà attraverso una rotazione di tonalità, quindi al punto 80%
della sequenza temporale, effettuerà la transizione dell'opacità da 1 a 0. Infine, la carta passa da display: block
a display: none
.
Per queste animazioni di uscita, invece di applicarle direttamente a un elemento, puoi impostare un attivatore per le animazioni. Ad esempio, collegando un listener di eventi a un pulsante che attiva una classe per applicare l'animazione, in questo modo:
.spin-out {
animation: spin-and-delete 1s ease-in forwards;
}
document.querySelector('.delete-btn').addEventListener('click', () => {
document.querySelector('.card').classList.add('spin-out');
})
L'esempio precedente ora ha uno stato finale display:none
. In molti casi conviene andare oltre e rimuovere il nodo DOM con un timeout per consentire il completamento dell'animazione per prima.
Transizione di animazioni discrete
A differenza dell'animazione di proprietà discrete con i fotogrammi chiave, per eseguire la transizione di proprietà discrete devi utilizzare la modalità di transizione allow-discrete
.
La proprietà transition-behavior
La modalità allow-discrete
è ciò che rende possibili le transizioni discrete ed è un valore della proprietà transition-behavior
. transition-behavior
accetta due valori: normal
e allow-discrete
.
.card {
transition: opacity 0.25s, display 0.25s;
transition-behavior: allow-discrete; /* Note: be sure to write this after the shorthand */
}
.card.fade-out {
opacity: 0;
display: none;
}
La forma abbreviata transition
imposta anche questo valore, quindi puoi omettere la proprietà e utilizzare invece la parola chiave allow-discrete
alla fine dell'abbreviazione transition
per ogni transizione.
.card {
transition: opacity 0.5s, display 0.5s allow-discrete;
}
.card.fade-out {
opacity: 0;
display: none;
}
Se stai animando più proprietà discrete, devi includere allow-discrete
dopo ogni proprietà che vuoi animare. Ad esempio:
.card {
transition: opacity 0.5s, display 0.5s allow-discrete, overlay 0.5s allow-discrete;
}
.card.fade-out {
opacity: 0;
display: none;
}
La regola @starting-style
per le animazioni delle voci
Finora questo articolo ha trattato le animazioni di uscita. Per creare animazioni di voce devi utilizzare la regola @starting-style
.
Utilizza @starting-style
per applicare uno stile che il browser può cercare prima che l'elemento sia aperto nella pagina. Questo è lo stato "prima dell'apertura" (da cui stai eseguendo l'animazione).
/* 0. BEFORE-OPEN STATE */
/* Starting point for the transition */
@starting-style {
.item {
opacity: 0;
height: 0;
}
}
/* 1. IS-OPEN STATE */
/* The state at which the element is open + transition logic */
.item {
height: 3rem;
display: grid;
overflow: hidden;
transition: opacity 0.5s, transform 0.5s, height 0.5s, display 0.5s allow-discrete;
}
/* 2. EXITING STATE */
/* While it is deleting, before DOM removal in JS, apply this
transformation for height, opacity, and a transform which
skews the element and moves it to the left before setting
it to display: none */
.is-deleting {
opacity: 0;
height: 0;
display: none;
transform: skewX(50deg) translateX(-25vw);
}
Ora sono presenti uno stato di ingresso e uno di uscita per questi elementi dell'elenco DA FARE:
Animazione di elementi da e verso il livello superiore
Per animare gli elementi da e verso il livello superiore, specifica @starting-style
nello stato "aperto" per indicare al browser da dove avviare l'animazione. Per una finestra di dialogo, lo stato di apertura è definito con l'attributo [open]
. Per un popover, utilizza la pseudo classe :popover-open
.
Un semplice esempio di finestra di dialogo potrebbe avere il seguente aspetto:
/* 0. BEFORE-OPEN STATE */
@starting-style {
dialog[open] {
translate: 0 100vh;
}
}
/* 1. IS-OPEN STATE */
dialog[open] {
translate: 0 0;
}
/* 2. EXIT STATE */
dialog {
transition: translate 0.7s ease-out, overlay 0.7s ease-out allow-discrete, display 0.7s ease-out allow-discrete;
translate: 0 100vh;
}
Nel prossimo esempio, gli effetti di entrata e uscita sono diversi. Inserisci un'animazione verso l'alto dalla parte inferiore dell'area visibile, esci dall'effetto nella parte superiore dell'area visibile. Inoltre, è scritto con CSS nidificato per una migliore incapsulamento visivo.
Quando anima un popover, utilizza la pseudo classe :popover-open
anziché l'attributo open
usato in precedenza.
.settings-popover {
&:popover-open {
/* 0. BEFORE-OPEN STATE */
/* Initial state for what we're animating *in* from,
in this case: goes from lower (y + 20px) to center */
@starting-style {
transform: translateY(20px);
opacity: 0;
}
/* 1. IS-OPEN STATE */
/* state when popover is open, BOTH:
what we're transitioning *in* to
and transitioning *out* from */
transform: translateY(0);
opacity: 1;
}
/* 2. EXIT STATE */
/* Initial state for what we're animating *out* to ,
in this case: goes from center to (y - 50px) higher */
transform: translateY(-50px);
opacity: 0;
/* Enumerate transitioning properties,
including display and allow-discrete mode */
transition: transform 0.5s, opacity 0.5s, display 0.5s allow-discrete;
}
overlay
struttura
Infine, per eliminare popover
o dialog
dal livello superiore, aggiungi la proprietà overlay
all'elenco delle transizioni. popover
e dialog
eseguono l'escape dei clip e delle trasformazioni predecessore e inseriscono i contenuti nel livello superiore. Se non esegui la transizione di overlay
, l'elemento tornerà immediatamente a essere ritagliato, trasformato e coperto, e non vedrai la transizione.
[open] {
transition: opacity 1s, display 1s allow-discrete;
}
Includi invece overlay
nella transizione o nell'animazione per animare overlay
insieme al resto degli elementi e assicurati che rimanga nel livello superiore durante l'animazione. L'operazione risulterà molto più fluida.
[open] {
transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}
Inoltre, se hai più elementi aperti nello strato superiore, la sovrapposizione ti aiuta a controllare la transizione fluida dentro e fuori il livello superiore. Puoi vedere la differenza in questo semplice esempio. Se non applichi overlay
al secondo popover al momento della transizione, questo uscirà dal strato superiore, passando dietro all'altro popover, prima di iniziare la transizione. L'effetto non è molto uniforme.
Una nota sulle transizioni delle viste
Se apporti modifiche al DOM, ad esempio aggiungi e rimuovi elementi dal DOM, un'altra ottima soluzione per creare animazioni fluide sono le transizioni di visualizzazione. Ecco due degli esempi precedenti creati utilizzando le transizioni di visualizzazione.
In questa prima demo, invece di configurare @starting-style
e altre trasformazioni CSS, le transizioni della vista gestiranno la transizione. La transizione della visualizzazione è impostata in questo modo:
Innanzitutto, assegna a ogni carta un singolo view-transition-name
in CSS.
.card-1 {
view-transition-name: card-1;
}
.card-2 {
view-transition-name: card-2;
}
/* etc. */
Quindi, in JavaScript, aggrega la mutazione del DOM (in questo caso, rimuovendo la scheda), in una transizione di visualizzazione.
deleteBtn.addEventListener('click', () => {
// Check for browser support
if (document.startViewTransition) {
document.startViewTransition(() => {
// DOM mutation
card.remove();
});
}
// Alternative if no browser support
else {
card.remove();
}
})
Ora il browser può gestire la dissolvenza in uscita e il morphing di ogni scheda nella nuova posizione.
Un altro esempio di come questa operazione può essere utile è la demo di aggiunta/rimozione degli elementi dell'elenco. In questo caso, dovrai ricordarti di aggiungere un view-transition-name
univoco per ogni carta creata.
Conclusione
Queste nuove funzionalità della piattaforma ci fanno un passo avanti per rendere fluide le animazioni di ingresso e uscita sulla piattaforma web. Per saperne di più, dai un'occhiata a questi link: