L'animation CSS est l'outil le plus pratique pour transformer un document statique en une expérience vivante et fluide. Sans écrire la moindre ligne de JavaScript, vous pouvez faire changer la couleur des boutons en douceur, faire glisser les cartes à l'écran et faire tourner les indicateurs de chargement — uniquement à l'aide de règles de style. Dans ce guide, je présenterai séparément les deux mécanismes fondamentaux : transition, qui se déclenche lors des changements d'état, et @keyframes, pour les mouvements chronométrés en plusieurs étapes.
transition : des changements d'état fluides
transition remplit automatiquement les étapes intermédiaires chaque fois que la valeur d'une propriété change. Ainsi, lorsqu'un :hover, un :focus ou une classe ajoutée par JavaScript modifie une couleur ou une taille, vous voyez un fondu progressif au lieu d'un saut brusque. Elle comporte quatre éléments clés : quelle propriété, sur quelle durée, avec quelle courbe d'accélération et après quel délai.
.btn {
background: #4f46e5;
transform: scale(1);
transition: background 200ms ease, transform 200ms ease;
}
.btn:hover {
background: #6366f1;
transform: scale(1.05);
}
Ici, le raccourci transition prend, dans l'ordre, la propriété, la durée et la fonction de temporisation. Vous pouvez lister plusieurs propriétés séparées par des virgules. Dans la mesure du possible, nommez les propriétés exactes au lieu d'utiliser all ; cela préserve des performances prévisibles et évite que des propriétés non souhaitées soient animées par erreur.
Fonctions de temporisation (easing)
Le caractère naturel d'un mouvement dépend en grande partie de sa courbe de vitesse. Dans le monde réel, les objets ne démarrent ni ne s'arrêtent brusquement ; ils accélèrent et ralentissent. CSS propose pour cela des mots-clés prêts à l'emploi et des courbes personnalisées :
ease— la valeur par défaut ; une courbe équilibrée qui démarre et finit en douceur.linear— vitesse constante ; idéal pour les indicateurs de chargement qui tournent.ease-out— démarre vite, finit lentement ; semble naturel pour les éléments qui entrent à l'écran.cubic-bezier(0.34, 1.56, 0.64, 1)— définit votre propre courbe ; les valeurs supérieures à 1 produisent un léger effet de « rebond ».
Pour la plupart des micro-interactions d'interface, des durées comprises entre 150 et 300 ms paraissent les plus naturelles. Trop courtes, le changement passe inaperçu ; trop longues, l'interface semble lourde.
@keyframes : les animations en plusieurs étapes
Une transition ne fonctionne qu'entre deux états : un début et une fin. Pour un mouvement en plusieurs phases — un élément qui grandit puis rétrécit, ou qui tourne en continu — on utilise @keyframes. Vous définissez d'abord une séquence d'images, puis vous l'appliquez à un élément avec la propriété animation.
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.1); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}
.badge {
animation: pulse 1.5s ease-in-out infinite;
}
Les pourcentages représentent des points sur la chronologie de l'animation ; from et to sont des raccourcis pour 0% et 100%. Le raccourci animation prend, dans l'ordre, le nom, la durée, l'easing, le nombre d'itérations (infinite pour une boucle sans fin) et la direction.
Performance : que faut-il animer ?
Une animation fluide vise 60 images par seconde. La clé pour y parvenir est d'animer des propriétés qui n'obligent pas le navigateur à recalculer la mise en page. transform et opacity sont traités directement sur le GPU sans déclencher de recalcul de mise en page, c'est pourquoi ils doivent être votre choix par défaut.
- Bien :
transform(translate, scale, rotate) etopacity. - À éviter :
width,height,top,left,margin— des propriétés qui déclenchent un reflow à chaque image.
Par exemple, pour faire glisser un élément vers la gauche, utilisez transform: translateX() plutôt que left. Si vous voulez signaler au navigateur qu'un élément est sur le point d'être animé, vous pouvez ajouter will-change: transform; — mais uniquement lorsque c'est réellement nécessaire, car en abuser consomme de la mémoire.
Accessibilité : respecter la préférence de mouvement réduit
Certains utilisateurs sont gênés par les mouvements excessifs ou les désactivent au niveau du système d'exploitation en raison de troubles vestibulaires. Honorer cette préférence avec la requête média prefers-reduced-motion est une bonne pratique :
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Cette règle désactive efficacement les animations décoratives tout en conservant une interface pleinement fonctionnelle.
Un exemple concret : une carte qui apparaît en fondu vers le haut
L'exemple ci-dessous fait apparaître une carte en la déplaçant légèrement du bas vers le haut et de la transparence vers l'opacité. Comme il n'utilise que transform et opacity, il reste fluide.
@keyframes fade-up {
from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: translateY(0); }
}
.card {
animation: fade-up 400ms ease-out both;
}
La valeur both signifie que l'animation conserve son état initial avant de démarrer et son état final après s'être terminée, de sorte que la carte reste en place sans scintiller.
Questions fréquentes
Quelle est la différence entre transition et animation ?
transition ne fonctionne qu'entre deux états, généralement en réponse à une interaction (hover, focus, changement de classe). animation, définie avec @keyframes, décrit un mouvement en plusieurs étapes qui peut démarrer seul et boucler.
Pourquoi mes animations saccadent-elles ?
Le coupable habituel est l'animation de propriétés comme width, top ou margin qui forcent un recalcul de la mise en page à chaque image. Passer à transform et opacity résout la plupart des saccades.
Puis-je déclencher une animation au défilement sans JavaScript ?
Oui. Dans les navigateurs modernes, les animations pilotées par le défilement sont possibles avec CSS animation-timeline: view();. Pour une prise en charge plus large, ajouter une classe via IntersectionObserver reste l'approche la plus fiable.
Vous souhaitez donner à votre interface une sensation soignée et fluide ? Si vous avez besoin d'aide pour des animations CSS performantes et des micro-interactions, contactez-moi.