Corso di CSS / Animazioni CSS con keyframe, fill-mode e pausa
Le animazioni CSS con keyframe (fotogrammi chiave) descrivono i valori delle proprietà lungo la timeline di un'animazione e possono essere eseguite senza un trigger di hover o focus. Durata, ritardo, numero di iterazioni, modalità di riempimento e stato di esecuzione controllano diverse parti di quel comportamento.
Distingui tra transizioni e animazioni keyframe
| standard | transizione | animazione |
|---|---|---|
| condizione iniziale | Quando il valore cambia a causa di hover, focus, cambiamento di classe, ecc. | Dopo che l'animazione è stata applicata e il tempo di ritardo è trascorso, |
| definizione dello stato | Valori CSS prima e dopo il cambiamento | Specifica valori iniziali, intermedi e finali nei keyframe |
| ripetizione e direzione | Procedi con i cambiamenti di stato | Specifica separatamente il numero di volte, la direzione e lo stato di stop |
La transizione è semplice finché cambia il colore di sfondo del pulsante. Puoi guardare le animazioni per effetti come quando appare per la prima volta una notifica o per una spiegazione visiva che attraversa diversi passaggi. Controllare la stessa proprietà sullo stesso elemento con due funzioni contemporaneamente rende difficile tenere traccia del valore applicato, quindi per questo esercizio dividiamo i ruoli. Se gli effetti prima e dopo il cambiamento di stato sono sufficienti, considera di iniziare con una semplice transizione consultando la lezione Trasformazioni e transizioni CSS.
Definisci i keyframe e le impostazioni di riproduzione
Nel keyframe, from corrisponde a 0% e to corrisponde a 100%. Se hai bisogno di uno stato intermedio, aggiungi una percentuale di progresso come 50%. Dichiarare solo un nome di keyframe non farà sì che venga eseguito; devi associarlo alla proprietà animation-name dell'elemento.
@keyframes travel {
0% { transform: translateX(0); }
50% { transform: translateX(3rem); }
100% { transform: translateX(6rem); }
}
.marker { animation: travel 4s linear 1s 1 normal forwards; }
Questo codice parziale è una versione abbreviata del keyframe e della configurazione .marker dello stesso nome nell'esempio completo qui sotto. 4s è il tempo necessario per l'esecuzione una volta e 1s è il ritardo di avvio. Se la durata non è specificata, il valore predefinito è 0 secondi, rendendo difficile osservare il processo in movimento. Puoi ridurre la confusione riguardo a tempo e frequenza suddividendoli inizialmente in proprietà dettagliate.
| Proprietà | Valori per questo esempio | Cose da cambiare |
|---|---|---|
animation-duration |
4s |
Durata di una riproduzione |
animation-timing-function |
linear |
Differenza tra progresso costante e curva ease |
animation-delay |
1s |
Tempo di attesa prima di iniziare |
animation-iteration-count |
1 |
Numero di riproduzioni; infinite ripete senza limite |
animation-direction |
normal |
Riproduzione avanti/indietro/alternata |
animation-fill-mode |
forwards |
Valore da applicare prima e dopo la fase attiva dell’animazione |
animation-play-state |
running predefinito |
Metti in pausa il progresso corrente con paused |
Anche con percentuali di keyframe equidistanti, la curva temporale può cambiare la velocità del movimento tra un fotogramma chiave e il successivo. Questo esercizio utilizza linear, che rende facile controllare le posizioni intermedie. Per la creazione e la connessione dei fotogrammi chiave, fare riferimento al documento MDN @keyframes.
Confrontare direzione, numero di iterazioni e modalità di riempimento
normal procede dall'inizio alla fine, e reverse procede dalla fine all'inizio. alternate si riproduce alternativamente in direzione forward la prima volta e in direzione inversa la volta successiva. Se il numero di iterazioni è 2 e alternato, l'ultima arriverà al primo fotogramma chiave.
forwards non è un'impostazione che mantiene sempre il keyframe al 100%. A seconda della direzione di riproduzione e del numero di volte, viene mantenuto il valore dell'ultimo fotogramma chiave effettivamente raggiunto. Nell'esempio, una volta nella direzione avanti mantiene la posizione di 6rem, una volta nella direzione inversa mantiene la posizione 0, e due volte in direzione alternata mantiene anch'essa la posizione 0. Questa descrizione si basa su un numero intero di riproduzioni completate, un numero frazionario potrebbe terminare a metà del progresso. Le condizioni per ogni direzione sono descritte in MDN: animation-fill-mode .
| fill-mode | Ritardo | Dopo il completamento |
|---|---|---|
none |
CSS di base | CSS di base |
forwards |
CSS di base | Ultimo fotogramma chiave riprodotto |
backwards |
Keyframe da riprodurre per primo | CSS di base |
both |
Keyframe da riprodurre per primo | Ultimo fotogramma chiave riprodotto |
Se il valore CSS di base e il valore finale del keyframe sono uguali, la differenza tra none e forwards può essere invisibile. La casella di movimento qui sotto ha una posizione predefinita di 1rem, un inizio di 0 e una fine di 6rem per mostrare la differenza. L’avviso da leggere, invece, ha uno stato CSS di base già visibile: resta leggibile anche senza animazione.
Esegui e modifica una impostazione alla volta
Salva il seguente codice come animation-lab.html in UTF-8 e aprilo nel tuo browser. L’avviso superiore compare con una breve animazione di ingresso e poi rimane visibile, e la casella decorativa inferiore inizia a muoversi dopo 1 secondo e si muove per 4 secondi. Dopo aver modificato i valori, salva il file e ricarica la pagina per confrontare dall'inizio.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Keyframes and end states exercise</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
.notice { padding: 1rem; border: 1px solid #90bdd8; border-radius: .5rem; background: #eaf4fa;
opacity: 1; transform: none; animation: appear 400ms ease-out; }
@keyframes appear {
from { opacity: 0; transform: translateY(.5rem); }
to { opacity: 1; transform: translateY(0); }
}
.track { margin-block: 1rem; padding: 1rem; border: 2px dashed #8a9ba7; }
.marker { width: 2rem; height: 2rem; border-radius: .25rem; background: #166b92;
transform: translateX(1rem);
animation-name: travel; animation-duration: 4s; animation-timing-function: linear;
animation-delay: 1s; animation-iteration-count: 1; animation-direction: normal;
animation-fill-mode: forwards; }
@keyframes travel {
0% { transform: translateX(0); background-color: #166b92; }
50% { transform: translateX(3rem); background-color: #6a3989; }
100% { transform: translateX(6rem); background-color: #28633b; }
}
#pause:checked ~ .track .marker { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
.notice, .marker { animation: none; }
}
</style>
</head>
<body>
<main>
<h1>Check entrance and movement</h1>
<p class="notice">This notice remains readable without animation.</p>
<h2>Comparing end states</h2>
<p>Movement starts one second after loading. Refresh the page to compare again.</p>
<input id="pause" type="checkbox"><label for="pause">Pause movement</label>
<div class="track"><div class="marker" aria-hidden="true"></div></div>
<p>The colors and movement are decorative. Essential information remains available independently of the animation, as in this sentence.</p>
</main>
</body>
</html>
- Nelle impostazioni predefinite, la scatola si trova in posizione 1rem durante il ritardo, si sposta a 0 all'inizio e rimane in posizione 6rem alla fine. Controlla la differenza tra il valore del ritardo e il valore iniziale.
- Cambia solo
animation-fill-modeinnonee aggiorna. Una volta terminato, torna alla posizione predefinita di 1rem e al colore blu predefinito. Ripristina a forwards. - Cambia solo fill-mode in
both. La posizione iniziale 0 si applica anche durante i ritardi. Dopo la conferma, torna a forwards. - Lascia animation-iteration-count a 1 e cambia la direzione in
reverse. Dopo il completamento, verifica che la posizione 0 rimanga e ripristina normal. - Verifica i risultati impostando la direzione su alternate e mantenendo il conteggio a 1. In quello stato, se cambi il numero a 2, avverrà una seconda riproduzione. Dopo la conferma, il conteggio è 1 e la direzione viene ripristinata a normal.
- Subito dopo l'aggiornamento, seleziona la casella Pause movement e aspetta un momento. Se togli il segno di spunta, continuerai da dove eri rimasto. Questo è diverso dalla possibilità di riprodurre dall'inizio.
Mantieni il contenuto visibile con movimento ridotto
L'impostazione ridotta rimuove l'animazione delle caselle di guida e decorazione. Le istruzioni sono ancora leggibili poiché il valore predefinito è opacity: 1 e la casella appare nella posizione predefinita di 1rem. Lasciare lo stato leggibile soltanto nei keyframe finali o in forwards può causare la scomparsa del contenuto in assenza di animazione.
Abilita il movimento ridotto nel pannello Rendering di DevTools o nel sistema operativo e ricarica. Entrambi gli elementi dovrebbero rimanere fermi mentre il loro contenuto rimane visibile. Consulta la guida MDN prefers-reduced-motion, quindi ripristina l'impostazione di emulazione dopo il confronto. Segui anche Verificare CSS responsive con larghezza, zoom e tastiera per controllare il ritaglio e l'usabilità con il movimento disabilitato.
Prima di aggiungere la ripetizione infinita, decidi perché il movimento è necessario e come si fermerà. Questo esempio utilizza iterazioni finite e fornisce informazioni importanti indipendentemente dal movimento e dal colore. Se nulla si muove, controlla il nome dell'animazione, la durata e la condizione di movimento ridotto. Per uno stato finale inaspettato, confronta la direzione, il numero di iterazioni, la modalità di riempimento e il CSS sottostante.




