Guide des animations CSS : transitions, keyframes et performances
Les animations CSS insufflent la vie aux interfaces, fournissant un retour visuel, guidant l'attention des utilisateurs et créant des expériences mémorables. Bien faites, les animations semblent naturelles et intuitives ; mal faites, elles provoquent des saccades, distraient les utilisateurs et peuvent même causer un inconfort physique. Ce guide couvre tout, des bases des transitions et keyframes à l'optimisation avancée des performances et à l'accessibilité, vous donnant les connaissances pour créer des animations fluides, intentionnelles et inclusives.
Transitions CSS vs animations
CSS offre deux mécanismes différents pour créer du mouvement : les transitions et les animations. Comprendre quand utiliser chaque mécanisme est fondamental pour travailler efficacement avec les animations CSS.
Transitions CSS
Les transitions ajoutent une animation aux changements d'une propriété CSS entre deux états. Vous définissez la propriété à animer, la durée de l'animation et la courbe d'accélération, et le navigateur gère automatiquement l'interpolation entre les valeurs de début et de fin. Les transitions sont déclenchées par des changements d'état, comme le survol, le focus, l'ajout de classe ou la modification de propriétés via JavaScript.
.button {
background: #3b82f6;
transform: scale(1);
transition: background 0.3s ease, transform 0.2s ease;
}
.button:hover {
background: #2563eb;
transform: scale(1.05);
}Les transitions sont parfaites pour les animations simples à deux états. Elles nécessitent un minimum de code, sont faciles à comprendre et fonctionnent de manière fiable dans les navigateurs. La limitation est qu'elles n'animent qu'entre deux valeurs — vous ne pouvez pas définir d'étapes intermédiaires.
Animations CSS (keyframes)
Les animations utilisent la règle @keyframes pour définir des séquences de changements de style avec un nombre arbitraire d'étapes. Contrairement aux transitions, les animations peuvent s'exécuter indépendamment des changements d'état, boucler indéfiniment, être lues à l'envers et mises en pause. Elles vous donnent un contrôle précis sur chaque image de l'animation.
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.05);
opacity: 0.8;
}
100% {
transform: scale(1);
opacity: 1;
}
}
.pulse-element {
animation: pulse 2s ease-in-out infinite;
}Quand utiliser laquelle
| Scénario | Utiliser transition | Utiliser animation |
|---|---|---|
| Effet de survol | Oui | Non |
| État de focus | Oui | Non |
| Bascule de visibilité | Oui | Peut-être |
| Séquence à plusieurs étapes | Non | Oui |
| Animation en boucle | Non | Indépendant de l'état |
| Non | Oui | Animation d'entrée |
| Peut-être | Oui | transform |
Syntaxe des keyframes en profondeur
La règle @keyframes est le cœur des animations CSS. Bien comprendre sa syntaxe libère toute la puissance des séquences d'animation à plusieurs étapes.
Keyframes basés sur des pourcentages
Les keyframes sont définis en utilisant des valeurs en pourcentage de 0 % à 100 %, représentant la progression sur la timeline de l'animation. Vous pouvez définir autant de keyframes que nécessaire, et le navigateur interpole entre eux :
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
25% {
transform: translateY(-20px);
}
50% {
transform: translateY(0);
}
75% {
transform: translateY(-10px);
}
}Plusieurs keyframes peuvent partager le même bloc de style en séparant les valeurs de pourcentage par des virgules, comme 0 %, 100 % dans l'exemple ci-dessus. C'est utile pour les animations qui reviennent à l'état de départ.
Propriété raccourcie d'animation
La propriété raccourcie animation combine huit sous-propriétés en une seule déclaration. L'ordre est : name, duration, timing-function, delay, iteration-count, direction, fill-mode et play-state.
.element {
animation: slideIn 0.5s ease-out 0.2s 1 forwards running;
}
/* Equivalent longhand */
.element {
animation-name: slideIn;
animation-duration: 0.5s;
animation-timing-function: ease-out;
animation-delay: 0.2s;
animation-iteration-count: 1;
animation-direction: normal;
animation-fill-mode: forwards;
animation-play-state: running;
}Mode de remplissage d'animation
La propriété animation-fill-mode contrôle quels styles sont appliqués avant et après l'exécution de l'animation. C'est l'une des propriétés d'animation les plus mal comprises :
- none (par défaut) : à la fin de l'animation, l'élément revient à son style d'avant l'animation.
- forwards : après la fin de l'animation, l'élément conserve le style de la dernière keyframe. Crucial pour les animations d'entrée où vous voulez que l'élément reste à sa position finale.
- backwards : pendant le délai de l'animation (avant qu'elle ne commence), l'élément applique le style de la première keyframe.
- both : combine les comportements forwards et backwards. L'élément affiche la première keyframe pendant le délai et conserve la dernière après la fin.
Fonctions d'accélération
Les fonctions d'accélération (aussi appelées fonctions de minutage) définissent la courbe d'accélération de l'animation. Elles déterminent si l'animation commence lentement puis accélère, commence rapidement puis ralentit, ou suit un modèle plus complexe. La bonne fonction d'accélération rend l'animation naturelle ; la mauvaise la rend mécanique ou abrupte.
Fonctions d'accélération intégrées
- linear : vitesse constante tout au long de l'animation. Rarement naturelle car les objets du monde réel ne se déplacent pas à vitesse constante. Convient aux animations mécaniques ou de rotation.
- ease (par défaut) : commence lentement, accélère au milieu, ralentit à la fin. Une bonne accélération générale pour la plupart des transitions UI.
- ease-in : commence lentement puis accélère. Crée un sentiment « d'élan qui se construit ». Convient aux éléments quittant l'écran ou tombant.
- ease-out : commence rapidement puis ralentit. Crée un sentiment « d'arrivée en place ». L'accélération la plus couramment utilisée pour les éléments UI entrant à l'écran.
- ease-in-out : début et fin lents, plus rapide au milieu. Similaire à ease mais avec une accélération et décélération plus prononcées. Convient aux transitions plus grandes et plus dramatiques.
Courbes de Bézier cubiques
La fonction cubic-bezier() vous permet de définir une courbe d'accélération personnalisée avec un contrôle précis. Elle accepte quatre paramètres représentant les points de contrôle d'une courbe de Bézier cubique : cubic-bezier(x1, y1, x2, y2). Les valeurs x représentent le temps (0 à 1), les valeurs y représentent la progression (peuvent dépasser 0-1 pour un effet de dépassement).
.element {
/* Smooth deceleration - great for entrances */
transition: transform 0.3s cubic-bezier(0.0, 0.0, 0.2, 1.0);
/* Smooth acceleration - great for exits */
transition: transform 0.2s cubic-bezier(0.4, 0.0, 1, 1);
/* Material Design standard easing */
transition: transform 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
}Fonctions en escalier
La fonction steps() crée des animations discrètes image par image plutôt qu'une interpolation fluide. C'est utile pour les animations de sprites ou la création d'effets de « frappe » :
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
.typing-effect {
animation: typing 3s steps(40, end);
overflow: hidden;
white-space: nowrap;
}Optimisation des performances
Les animations fluides nécessitent d'atteindre 60 images par seconde (fps), ce qui signifie que chaque image doit être terminée en 16,67 millisecondes. Ne pas respecter ce budget provoque des saccades visibles — tremblements de l'image, images perdues et dégradation de l'expérience utilisateur. Comprendre le pipeline de rendu du navigateur est essentiel pour écrire des animations performantes.
Pipeline de rendu
Lorsqu'une propriété CSS change, le navigateur passe par jusqu'à trois étapes pour mettre à jour l'affichage :
- Style : détermine quelles règles CSS s'appliquent à quels éléments.
- Layout : calcule la taille et la position de chaque élément. Déclenché par les changements de width, height, margin, padding, top, left, font-size et d'autres propriétés géométriques.
- Peinture : remplit les pixels pour chaque élément. Déclenchée par les changements de color, background, box-shadow, border-radius et d'autres propriétés visuelles.
- Composition : combine les calques peints dans le bon ordre. Seule cette étape s'exécute sur le GPU. Déclenchée par les changements de transform et opacity.
Les animations qui ne déclenchent que l'étape de composition ont les meilleures performances car elles skipentent entièrement le layout et la peinture. C'est pourquoi transform et opacity sont la référence en or des animations CSS performantes.
Propriétés de composition uniquement
| Propriété | Déclenche le layout ? | Déclenche la peinture ? | Composition GPU ? |
|---|---|---|---|
| Non | Non | Oui | opacity |
| Non | Non | Oui | filter |
| Non | Oui | Parfois | top / left |
| Oui | Oui | Non | width / height |
| Oui | Oui | Non | margin / padding |
| Oui | Oui | Non | background-color |
| Non | Oui | Non | box-shadow |
| Non | Oui | Non | No |
Utilisation de will-change
La propriété will-change indique au navigateur quelles propriétés sont susceptibles de changer, lui permettant d'optimiser à l'avance en promouvant l'élément sur son propre calque de composition. Cependant, elle doit être utilisée avec prudence :
/* Apply will-change just before the animation */
.element:hover {
will-change: transform;
}
/* Remove it after the animation completes */
.element {
transition: transform 0.3s ease;
}Les erreurs courantes avec will-change incluent son application à trop d'éléments (chaque calque de composition consomme de la mémoire GPU) et sa conservation permanente (gaspillage de ressources). Une bonne pratique consiste à ajouter will-change via JavaScript juste avant le début de l'animation et à le retirer après la fin de l'animation.
Utiliser Transform au lieu des propriétés de layout
L'optimisation des performances la plus efficace consiste à remplacer les propriétés déclenchant le layout par transform :
- Utiliser transform: translateX(100px) au lieu de left: 100px
- Utiliser transform: translateY(50px) au lieu de top: 50px
- Utiliser transform: scale(1.5) au lieu de width: 150%; height: 150%
- Utiliser transform: rotate(45deg) au lieu d'une rotation via le layout
Modèles d'animation courants
Certains modèles d'animation reviennent constamment dans les interfaces web. Maîtriser ces modèles vous donne une boîte à outils pour la plupart des besoins d'animation UI courants.
1. Fondu entrant
L'animation d'entrée la plus simple et la plus polyvalente. L'élément passe de transparent à opaque :
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 0.4s ease-out forwards;
}2. Fondu entrant avec glissement vers le haut
Un effet d'entrée plus dynamique, combinant un mouvement vertical et un changement d'opacité. Cela crée le sentiment que l'élément arrive d'en dessous :
@keyframes slideUpFade {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.slide-up {
animation: slideUpFade 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}3. Agrandissement au survol
Un agrandissement subtil au survol fournit un retour d'interaction satisfaisant :
.card {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.card:hover {
transform: translateY(-4px) scale(1.02);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
}4. Animation de liste en décalé
Lorsqu'une liste d'éléments apparaît, définir un délai d'animation décalé pour chaque élément crée un effet en cascade qui guide le regard :
.list-item {
opacity: 0;
transform: translateY(10px);
animation: slideUpFade 0.3s ease-out forwards;
}
.list-item:nth-child(1) { animation-delay: 0.0s; }
.list-item:nth-child(2) { animation-delay: 0.05s; }
.list-item:nth-child(3) { animation-delay: 0.1s; }
.list-item:nth-child(4) { animation-delay: 0.15s; }
.list-item:nth-child(5) { animation-delay: 0.2s; }Pour les listes dynamiques, utilisez JavaScript pour définir le animation-delay en fonction de l'index de chaque élément, ou utilisez une propriété personnalisée CSS : style="animation-delay: calc(var(--i) * 0.05s)".
5. Indicateur de chargement rotatif
Une rotation continue et fluide est un indicateur de chargement classique :
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
width: 24px;
height: 24px;
border: 3px solid rgba(255, 255, 255, 0.2);
border-top-color: #3b82f6;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}Accessibilité des animations : prefers-reduced-motion
Tous les utilisateurs ne bénéficient pas des animations. Pour les personnes souffrant de troubles vestibulaires, de sensibilité au mouvement ou de certaines conditions cognitives, les animations peuvent provoquer des vertiges, des nausées ou des crises d'épilepsie. La media query prefers-reduced-motion vous permet de respecter la préférence de réduction d'animation au niveau du système de l'utilisateur.
Implémenter la réduction des animations
L'approche recommandée consiste à activer les animations pour les utilisateurs qui n'ont pas défini de préférence de réduction :
/* Default: no animation for users who prefer reduced motion */
.element {
opacity: 1;
transform: none;
}
/* Only animate for users who have no motion preference */
@media (prefers-reduced-motion: no-preference) {
.element {
animation: slideUpFade 0.5s ease-out forwards;
}
}Alternativement, vous pouvez désactiver des animations spécifiques pour les utilisateurs préférant réduire les animations :
.element {
animation: slideUpFade 0.5s ease-out forwards;
}
@media (prefers-reduced-motion: reduce) {
.element {
animation: none;
opacity: 1;
transform: none;
}
/* Keep functional transitions but shorten duration */
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}Que conserver et que supprimer
Lorsque l'utilisateur préfère réduire les animations, toutes les animations ne devraient pas être supprimées. Les animations fonctionnelles qui communiquent du sens ou un état devraient être conservées, simplement simplifiées :
- Supprimer : animations décoratives, défilement parallaxe, carrousels en lecture automatique, effets de pulsation et animations d'arrière-plan en boucle.
- Simplifier : la durée des transitions devrait être raccourcie à presque instantanée (0.01ms) plutôt que totalement supprimée, afin que les changements d'état restent perceptibles.
- Conserver : les transitions d'état fonctionnelles (survol, focus, état actif), les indicateurs de progression et toute animation communiquant des informations importantes.
Bibliothèques d'animation
Bien que les animations CSS gèrent la plupart des besoins UI, les bibliothèques d'animation JavaScript offrent des fonctionnalités avancées comme le mouvement basé sur la physique, les animations liées au défilement et l'orchestration de séquences complexes.
Bibliothèques CSS d'abord
- Animate.css : une collection de classes d'animation CSS préconstruites. Ajoutez simplement un nom de classe à un élément pour appliquer l'animation. Convient au prototypage rapide, mais peut donner un effet générique si surutilisé.
- Hamburgers : une collection de transitions d'icônes de menu hamburger animées, toutes en CSS pur.
Bibliothèques d'animation JavaScript
- Framer Motion : une bibliothèque d'animation React offrant une API d'animation déclarative, avec support de la physique des ressorts, des animations de layout et des gestes. Le meilleur choix pour les applications React.
- GSAP (GreenSock) : la bibliothèque d'animation JavaScript la plus puissante. Offre un contrôle précis de la timeline, des accélérations complexes, la morphing SVG et les animations déclenchées par le défilement. Utilisée par les grandes marques pour les sites marketing et les expériences interactives.
- Anime.js : une bibliothèque d'animation JavaScript légère avec une API concise. Prend en charge les propriétés CSS, SVG, les attributs DOM et les objets JavaScript. Un bon choix intermédiaire entre CSS et GSAP.
- Motion One : une bibliothèque d'animation moderne et légère construite sur l'API Web Animations. Offre une API minimaliste avec support de la physique des ressorts et des timelines.
Quand utiliser JavaScript vs CSS
CSS pour les animations déclaratives simples en réponse à des changements d'état. JavaScript pour : le mouvement basé sur la physique (ressorts, inertie), les animations liées au défilement, les séquences complexes avec un contrôle précis du minutage, les paramètres d'animation dynamiques calculés à l'exécution, ou les animations devant être mises en pause, inversées ou glissées par programmation.
Débogage des animations
Les bugs d'animation peuvent être subtils et difficiles à diagnostiquer. Les bons outils et techniques de débogage rendent le processus beaucoup plus efficace.
Panneau d'animation Chrome DevTools
Chrome DevTools inclut un panneau d'animation dédié offrant de puissantes fonctionnalités de débogage :
- Vue timeline : voir toutes les animations actives sur la page avec leurs durées, délais et keyframes.
- Contrôles de lecture : ralentir les animations au 1/4 de la vitesse, mettre en pause ou faire glisser la timeline image par image.
- Inspection des propriétés : cliquez sur une animation dans la timeline pour voir les propriétés CSS exactes animées et leurs valeurs à chaque keyframe.
- Édition en direct : modifiez la durée, le délai et l'accélération de l'animation en direct sans recharger la page.
Analyse des performances
Utilisez le panneau Performance dans Chrome DevTools pour identifier les saccades d'animation :
- Enregistrer une trace de performance pendant que l'animation s'exécute
- Rechercher les images dépassant le budget de 16.67ms (affichées comme des barres rouges dans le graphique d'images)
- Vérifier si les images d'animation contiennent des opérations « Layout », ce qui indique des propriétés déclenchant le layout
- Utiliser l'onglet « Rendering » pour activer « Paint flashing » (affiche les zones repeintes en vert) et « Layer borders » (affiche les calques de composition)
Scénarios de débogage courants
- L'animation ne s'exécute pas : vérifiez si animation-fill-mode est correctement défini. Sans forwards ou both, l'élément revient à son état d'avant l'animation. Vérifiez également que l'élément a les bonnes dimensions — transform: scale(0) rend l'élément invisible mais il existe toujours.
- L'animation saccade : ouvrez le panneau Performance pour trouver les images longues. Vérifiez si l'animation déclenche des propriétés de layout. Passez à transform et opacity.
- Le délai d'animation ne semble pas correct : rappelez-vous que animation-delay crée un intervalle avant le début de l'animation. Pendant cet intervalle, à moins que vous ne définissiez animation-fill-mode: backwards ou both, l'élément affiche son état d'avant l'animation.
- L'animation fonctionne dans Chrome mais pas dans Safari : Safari est plus strict dans l'analyse du raccourci animation. Assurez-vous que toutes les valeurs sont dans le bon ordre et qu'aucune fonctionnalité non prise en charge n'est utilisée.
Vous utilisez CSS ? Essayez nos outils CSS gratuits pour formater, minifier et optimiser vos feuilles de style pour la production.
Formateur CSSMinificateur CSSQuestions fréquentes
Faut-il utiliser les transitions CSS ou les animations CSS ?
Les transitions CSS sont utilisées pour les changements d'état simples d'un point A à un point B, comme les effets de survol, les états de focus et le basculement de visibilité. Les animations CSS (keyframes) sont utilisées pour les séquences complexes à plusieurs étapes, les animations en boucle ou les animations devant s'exécuter indépendamment des changements d'état. Les transitions sont plus simples ; les animations offrent plus de contrôle.
Quelles propriétés CSS peuvent être animées en toute sécurité pour les performances ?
Les propriétés les plus performantes à animer sont transform et opacity car elles peuvent être entièrement traitées par le compositeur GPU sans déclencher de layout ou de peinture. D'autres propriétés comme width, height, margin et top déclenchent un recalcul du layout, ce qui est coûteux. Privilégiez toujours transform: translateX() plutôt que left, et transform: scale() plutôt que les changements de width/height.
Comment fournir une accessibilité aux utilisateurs sensibles aux animations ?
Utilisez la media query prefers-reduced-motion pour désactiver ou simplifier les animations pour les utilisateurs ayant activé le paramètre « réduire les animations » dans leur système d'exploitation. Enveloppez les animations non essentielles dans @media (prefers-reduced-motion: no-preference) et fournissez des changements d'état instantanés comme solution de repli pour les utilisateurs préférant réduire les animations.
Qu'est-ce que will-change et quand faut-il l'utiliser ?
will-change est une propriété CSS qui indique au navigateur quelles propriétés vont changer à l'avenir, lui permettant d'optimiser à l'avance. Utilisez-la avec parcimonie, uniquement lorsque vous observez des problèmes de performances. Appliquez-la avant le début de l'animation et retirez-la après la fin. Une utilisation excessive de will-change gaspille la mémoire GPU et peut en fait nuire aux performances.
Comment déboguer les animations CSS ?
Chrome DevTools offre de puissants outils de débogage d'animation. Ouvrez le panneau d'animation (dans le menu Plus d'outils) pour voir toutes les animations actives, faire glisser la timeline, modifier en direct les durées et les délais, et ralentir les animations au 1/4 de la vitesse. Vous pouvez également utiliser le panneau Performance pour identifier les saccades d'animation et les tremblements de layout.