Kodokon kodokon.com

Transitions et animations : @keyframes, transform, timing

Animez au niveau du compositeur avec transform et opacity, structurez vos @keyframes et respectez les préférences de mouvement des utilisateurs.

10 min · 3 questions

Ouvrir cette leçon dans Kodokon

Avant de choisir quoi animer, rappelez-vous le pipeline de rendu : layout (géométrie), paint (pixels), composite (assemblage des calques sur le GPU). Animer width ou top déclenche un layout à chaque frame, souvent suivi d'un paint : c'est la recette du jank sous 60 fps. transform et opacity sont traitées directement par le compositeur, sans repasser par les deux premières étapes. La règle du métier : n'animez que ces deux propriétés dès que possible, et simulez le reste (translate au lieu de top, scale au lieu de width).

CSS
.button {
  transform: translateY(0);
  transition:
    transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity 0.15s ease-out;
}

.button:hover {
  transform: translateY(-2px);
}

.button:active {
  transform: translateY(0) scale(0.97);
}
Transition compositor-friendly avec courbe custom

Quand une transition ne suffit plus (étapes intermédiaires, boucle, départ automatique), passez à @keyframes. Deux réglages font la différence entre une animation propre et un bug visuel : animation-fill-mode contrôle l'état avant le départ (backwards applique la première keyframe pendant le délai) et après la fin (forwards fige la dernière) ; both combine les deux. Par ailleurs, la timing function s'applique entre chaque paire de keyframes, pas sur la durée totale : vous pouvez la redéfinir à l'intérieur d'une keyframe.

CSS
@keyframes slide-in {
  from {
    transform: translateX(-100%);
    opacity: 0;
  }
  70% {
    transform: translateX(8px);
    opacity: 1;
  }
  to {
    transform: translateX(0);
  }
}

.toast {
  animation: slide-in 0.35s ease-out both;
}
Entrée avec léger dépassement (overshoot)

Deux outils complémentaires à connaître. will-change: transform promeut l'élément sur son propre calque avant l'animation, évitant un raster tardif ; mais chaque calque coûte de la mémoire GPU, donc appliquez-le juste avant l'animation et retirez-le après, jamais en style permanent sur des dizaines d'éléments. steps(n) remplace l'interpolation continue par des sauts discrets : indispensable pour les sprites, les curseurs de type machine à écrire ou les horloges.

CSS
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
Respecter prefers-reduced-motion

Quiz de validation

Vérifiez que vous avez bien retenu les points clés de cette leçon.

  1. Pourquoi préférer transform: translateX(100px) à left: 100px pour un déplacement animé ?
    • transform est mieux supporté par les anciens navigateurs
    • transform est traité par le compositeur sans recalcul de layout à chaque frame
    • left ne fonctionne que sur les éléments en position absolue, transform partout
    • transform accepte des valeurs négatives, contrairement à left
  2. Que fait animation-fill-mode: both ?
    • L'animation se joue à l'aller puis à l'envers
    • L'animation s'applique à l'élément et à ses descendants
    • Les styles de la première keyframe s'appliquent pendant le délai, ceux de la dernière persistent après la fin
  3. Quel est le bon usage de will-change ?
    • L'appliquer globalement sur * pour accélérer toute la page
    • L'ajouter juste avant une animation coûteuse et le retirer ensuite
    • Le combiner systématiquement avec transform: translateZ(0)
    • L'utiliser à la place de transition pour les micro-interactions