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. Sono incluse la possibilità di animare facilmente le animazioni di entrata e di uscita e di animare senza interruzioni verso e dal livello superiore per gli elementi ignorabili, come finestre di dialogo e popup.
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
in una sequenza temporale dei fotogrammi chiave (da Chrome 116). - La proprietà
transition-behavior
con la parola chiaveallow-discrete
per abilitare le transizioni di proprietà discrete comedisplay
(da Chrome 117). - La regola
@starting-style
per animare gli effetti di inserimento 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).
Mostrare le 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 per supportare questa funzionalità:
.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 imposta la visualizzazione su nessuno. Inoltre, la parola chiave forwards
garantisce che l'animazione rimanga nel suo stato finale, in modo che l'elemento a cui viene applicata rimanga display: none
e opacity: 0
.
Questo è un semplice esempio che mostra cosa puoi fare con una transizione (vedi la demo nella sezione relativa alle transizioni). Tuttavia, le transizioni 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. Innanzitutto, la scheda ruota sull'asse Y, esegue una rotazione di tonalità e, al punto 80%
della sequenza temporale, la sua opacità passa da 1 a 0. Infine, la scheda passa da display: block
a display: none
.
Per queste animazioni di uscita, invece di applicarle direttamente a un elemento, puoi configurare un attivatore per le animazioni. Ad esempio, collegando un gestore di eventi a un pulsante che attiva una classe per applicare l'animazione, come segue:
.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 riportato sopra ora ha uno stato finale di display:none
. In molti casi, ti consigliamo di andare oltre e rimuovere il nodo DOM con un timeout per consentire il completamento dell'animazione.
Transizioni di animazioni distinte
A differenza dell'animazione di proprietà discrete con i fotogrammi chiave, per applicare transizioni a proprietà discrete devi utilizzare la modalità di comportamento di transizione allow-discrete
.
La proprietà transition-behavior
La modalità allow-discrete
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;
}
Anche la scorciatoia transition
imposta questo valore, quindi puoi omettere la proprietà e utilizzare la parola chiave allow-discrete
alla fine della scorciatoia 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à distinte, devi includere allow-discrete
dopo ogni proprietà da 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 di entrata
Finora questo articolo ha trattato le animazioni di uscita. Per creare animazioni di entrata, devi utilizzare la regola @starting-style
.
Utilizza @starting-style
per applicare uno stile che il browser può cercare prima che l'elemento venga aperto nella pagina. Questo è lo stato "prima dell'apertura" (da dove parte l'animazione).
/* 0. 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;
}
/* 1. BEFORE-OPEN STATE */
/* Starting point for the transition */
@starting-style {
.item {
opacity: 0;
height: 0;
}
}
/* 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 verso e dal livello superiore, specifica @starting-style
nello stato "aperto" per indicare al browser da dove iniziare l'animazione. Per una finestra di dialogo, lo stato aperto è definito con l'attributo [open]
. Per un popup, utilizza la pseudo classe :popover-open
.
Un semplice esempio di finestra di dialogo potrebbe avere il seguente aspetto:
/* 0. IS-OPEN STATE */
dialog[open] {
translate: 0 0;
}
/* 1. BEFORE-OPEN STATE */
@starting-style {
dialog[open] {
translate: 0 100vh;
}
}
/* 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;
}
Nell'esempio seguente, gli effetti di entrata e di uscita sono diversi. Inserisci l'animazione dall'alto verso il basso della visualizzazione e esci dall'effetto verso la parte superiore della visualizzazione. Inoltre, è scritto con CSS nidificato per una migliore incapsulamento visivo.
Quando animi un popup, utilizza la pseudoclasse :popover-open
anziché l'attributo open
utilizzato in precedenza.
.settings-popover {
&:popover-open {
/* 0. IS-OPEN STATE */
/* state when popover is open, BOTH:
what we're transitioning *in* to
and transitioning *out* from */
transform: translateY(0);
opacity: 1;
/* 1. 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;
}
}
/* 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 attenuare un popover
o un dialog
dal livello superiore, aggiungi la proprietà overlay
all'elenco delle transizioni. popover
e dialog
escono dai clip e dalle trasformazioni degli antenati e inseriscono i contenuti nel livello superiore. Se non esegui la transizione 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 animarlo insieme alle altre funzionalità 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, quando hai più elementi aperti nel livello superiore, l'overlay ti aiuta a controllare la transizione fluida all'interno e all'esterno del livello superiore. Puoi vedere la differenza in questo semplice esempio. Se non applichi overlay
al secondo popup durante la transizione, prima uscirà dal livello superiore, passando dietro l'altro popup, prima di iniziare la transizione. L'effetto non è molto uniforme.
Una nota sulle transizioni di visualizzazione
Se apporti modifiche al DOM, ad esempio aggiungi e rimuovi elementi dal DOM, un'altra ottima soluzione per animazioni fluide è rappresentata dalle 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 di visualizzazione è configurata nel seguente 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. */
Poi, in JavaScript, inserisci la mutazione DOM (in questo caso, la rimozione della 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 l'attenuazione e la trasformazione 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, devi ricordare di aggiungere un view-transition-name
univoco per ogni scheda creata.
Conclusione
Queste nuove funzionalità della piattaforma ci avvicinano a animazioni di entrata e uscita fluide sulla piattaforma web. Per saperne di più, dai un'occhiata a questi link: