Cours CSS / animations : images clés, fill-mode et pause

Les animations CSS à images clés (keyframes) décrivent les valeurs des propriétés sur la timeline d'une animation et peuvent s'exécuter sans déclencheur de survol ou de focus. La durée, le délai, le nombre d'itérations, le mode de remplissage et l'état de lecture contrôlent différentes parties de ce comportement.

Distinguer les transitions et les animations keyframe

Critère transition animation
condition de départ Lorsque la valeur change en raison du survol, du focus, du changement de classe, etc. Après que l'animation a été appliquée et que le temps de retard est écoulé,
définition de l'état Valeurs CSS avant et après le changement Spécifiez les valeurs de début, milieu et fin dans les keyframes
répétition et direction Procéder aux changements d'état Spécifiez séparément le nombre de fois, la direction et l'état d'arrêt

Une transition suffit souvent pour changer la couleur de fond d’un bouton. Une animation à images clés convient aussi à une apparition initiale ou à une séquence comportant plusieurs étapes. Évitez de piloter la même propriété du même élément par les deux mécanismes à la fois pendant cet exercice : il deviendrait plus difficile d’identifier la valeur appliquée. Si une variation entre deux états suffit, commencez par les transformations et transitions CSS.

Définir les images clés et les paramètres de lecture

Dans le keyframe, from correspond à 0%, et to correspond à 100%. Si vous avez besoin d'un état intermédiaire, ajoutez un pourcentage de progression comme 50%. Déclarer simplement un nom de keyframe ne le fera pas jouer ; vous devez l'associer au animation-name de l'élément.

@keyframes travel {
  0% { transform: translateX(0); }
  50% { transform: translateX(3rem); }
  100% { transform: translateX(6rem); }
}
.marker { animation: travel 4s linear 1s 1 normal forwards; }

Ce code partiel est une version abrégée du keyframe et du paramétrage .marker du même nom dans l'exemple complet ci-dessous. 4s est le temps nécessaire pour jouer une fois et 1s est le délai de démarrage. Si la durée n'est pas spécifiée, la valeur par défaut est de 0 seconde, rendant difficile l'observation du processus en mouvement. Vous pouvez réduire la confusion concernant le temps et la fréquence en les divisant d'abord en propriétés détaillées.

Propriété Valeurs pour cet exemple Choses à changer
animation-duration 4s Durée d’une lecture
animation-timing-function linear Différence entre progression constante et courbe ease
animation-delay 1s Temps d'attente avant de commencer
animation-iteration-count 1 Nombre de lectures ; infinite répète sans limite
animation-direction normal Lecture avant/arrière/alternée
animation-fill-mode forwards Valeurs appliquées avant et après la phase de lecture
animation-play-state running par défaut Mettre la progression en pause avec paused

Même si les pourcentages des images clés sont espacés régulièrement, le changement réel de position variera en fonction du temps. Cet exercice utilise linear, ce qui facilite la vérification des positions intermédiaires. Pour la création et la connexion de keyframes, référez-vous au document MDN @keyframes .

Comparer la direction, le nombre d'itérations et le mode de remplissage

normal procède du début à la fin, et reverse procède de la fin au début. alternate joue alternativement dans le sens avant la première fois et dans le sens inverse la fois suivante. Si le nombre d'itérations est de 2 et en alternance, la dernière arrivera au premier keyframe.

forwards ne conserve pas systématiquement la valeur de l’image clé à 100%. Selon la direction de lecture et le nombre de fois, la valeur de la dernière image clé effectivement atteinte est maintenue. Dans l'exemple, une fois dans la direction avant maintient la position de 6rem, une fois dans la direction inverse maintient la position de 0, et deux fois dans la direction alternée maintient également la position de 0. Cette description est basée sur un nombre entier de lectures complètes, un nombre fractionnel peut se terminer en cours de progression. la documentation MDN sur animation-fill-mode .

fill-mode Délai Après la fin
none CSS de base CSS de base
forwards CSS de base Dernière image clé jouée
backwards Premier keyframe à jouer CSS de base
both Premier keyframe à jouer Dernière image clé jouée

Si la valeur CSS de base et la valeur du keyframe final sont les mêmes, la différence entre none et forwards peut être invisible. La boîte de mouvement ci-dessous a une position par défaut de 1rem, un début de 0 et une fin de 6rem pour révéler la différence. D'un autre côté, l’avis à lire conserve dans son CSS de base l’état visible à utiliser quand l’animation est désactivée.

Exécutez et modifiez un paramètre à la fois

Enregistrez le code suivant sous animation-lab.html en UTF-8 et ouvrez-le dans votre navigateur. L’avis supérieur apparaît avec une courte animation, puis reste visible et la boîte décorative inférieure commence à bouger après 1 seconde et se déplace pendant 4 secondes. Après avoir modifié les valeurs, enregistrez le fichier et rechargez la page pour comparer depuis le début.

<!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>
  1. Dans les paramètres par défaut, la boîte est à la position 1rem pendant le délai, se déplace à 0 au début, et reste à la position 6rem à la fin. Vérifiez la différence entre la valeur du délai et la valeur de début.
  2. Changez uniquement animation-fill-mode en none et actualisez. Une fois terminé, elle revient à la position par défaut de 1rem et à la couleur bleue par défaut. Restaurez à forwards.
  3. Changez uniquement fill-mode en both. La position de départ 0 s'applique même pendant les délais. Après confirmation, revenez à forwards.
  4. Laissez le compte à 1 et changez la direction en reverse. Après l'exécution, vérifiez que la position 0 reste et rétablissez normal.
  5. Vérifiez les résultats en changeant animation-direction en alternate et en gardant le compte à 1. Dans cet état, si vous changez le nombre à 2, une deuxième lecture se produira. Après confirmation, le compte est de 1 et la direction est rétablie à normal.
  6. Immédiatement après le rafraîchissement, cochez la case Pause et attendez un instant. Si vous l'annulez, vous continuerez là où vous vous étiez arrêté. Cela est différent de la possibilité de rejouer depuis le début.

Gardez le contenu visible avec un mouvement réduit

Le paramètre réduit supprime l'animation des boîtes de guidage et de décoration. Les instructions restent lisibles car le réglage par défaut est opacity: 1 et la boîte apparaît à la position par défaut de 1rem. Laisser l'état lisible uniquement dans les images clés finales ou avec forwards peut provoquer la disparition du contenu en l'absence d'animation.

Activez le mouvement réduit dans le panneau Rendu de DevTools ou dans le système d'exploitation et rechargez. Les deux éléments devraient rester immobiles tout en gardant leur contenu visible. Consultez le guide MDN prefers-reduced-motion, puis restaurez le réglage d'émulation après la comparaison. Suivez également Vérifier le design adaptatif : largeur, zoom et clavier pour vérifier le rognage et l'utilisabilité lorsque le mouvement est désactivé.

Avant d'ajouter une répétition infinie, décidez pourquoi le mouvement est nécessaire et comment il s'arrêtera. Cet exemple utilise des itérations finies et fournit des informations importantes indépendamment du mouvement et de la couleur. Si rien ne bouge, vérifiez le nom de l'animation, sa durée et la condition de mouvement réduit. Pour un état final inattendu, comparez la direction, le nombre d'itérations, le mode de remplissage et le CSS sous-jacent.