Publié le 15 mars 2024

Les animations CSS complexes semblent nécessiter JavaScript, mais la clé est de voir les `@keyframes` non comme du code, mais comme une véritable timeline de réalisateur.

  • Une animation `@keyframes` n’est pas un simple changement d’état, mais un scénario complet avec des étapes clés définies en pourcentages (0%, 50%, 100%).
  • Pour une fluidité maximale (60fps), il est impératif de n’animer que les propriétés `transform` et `opacity`, qui sont gérées par le GPU.

Recommandation : Avant d’écrire la moindre ligne de code, dessinez votre animation sur le papier : définissez son point de départ, son point d’arrivée et toutes les étapes intermédiaires. Pensez en termes de scénario, pas de syntaxe.

Vous avez maîtrisé les transitions CSS. Un bouton qui change de couleur au survol, une image qui s’agrandit doucement… ces petites interactions fluides sont devenues une seconde nature. Mais voilà, vous voulez plus. Vous imaginez un logo qui apparaît, s’arrête, palpite légèrement puis s’efface. Vous pensez à une icône qui fait un tour complet, marque une pause, puis repart. Immédiatement, votre réflexe de développeur s’active : « Il va falloir sortir JavaScript ». Cette pensée est compréhensible, car les transitions se limitent à un voyage simple entre un état A et un état B.

Et si cette approche était une fausse route ? Si le CSS natif possédait déjà un outil d’une puissance narrative insoupçonnée, capable de gérer des séquences complexes sans alourdir votre page ? Cet outil, ce sont les `@keyframes`. L’erreur commune est de les voir comme une « super transition ». C’est une erreur de perspective. Les `@keyframes` ne sont pas une propriété, c’est un véritable banc de montage, une timeline sur laquelle vous, le développeur, devenez le metteur en scène. Vous n’allez pas simplement définir un début et une fin, vous allez écrire un scénario complet, image clé par image clé.

Cet article vous propose de changer de casquette. Oubliez un instant le développeur pour devenir réalisateur. Nous allons apprendre à penser une animation en termes de séquences, de rythme et de timing. Nous verrons comment utiliser la timeline `@keyframes` pour définir chaque étape de notre histoire, comment piloter la lecture avec les propriétés `animation-*` comme sur une table de mixage, et surtout, comment garantir un spectacle fluide et performant en faisant travailler les bons « techniciens » : le GPU plutôt que le CPU.

Pour vous guider dans cet apprentissage, nous allons décomposer le processus de création, de la compréhension de la timeline à la maîtrise des propriétés avancées. Préparez-vous à découvrir le potentiel cinématographique qui se cache dans vos feuilles de style.

La timeline de votre animation : comprendre la syntaxe de base de @keyframes

Avant de réaliser un film, on écrit un scénario avec des scènes clés. En CSS, c’est exactement la même chose. Une règle `@keyframes` est votre scénario. La première étape est de lui donner un nom, comme on donnerait un titre à une séquence. C’est ce nom qui permettra ensuite d’appeler l’animation sur un élément précis. Par exemple : `@keyframes apparitionEnFondu { … }`.

À l’intérieur de ce scénario, vous devez définir les moments cruciaux : les images clés (les « keyframes »). Ces moments sont marqués par des pourcentages, de `0%` (le tout début de l’animation) à `100%` (la toute fin). Pour chaque pourcentage, vous décrivez l’état de votre élément : sa couleur, sa position, sa taille, etc. Pour une animation simple en deux temps, on peut utiliser les mots-clés `from` (équivalent à `0%`) et `to` (équivalent à `100%`).

Mais la véritable puissance se révèle avec les étapes intermédiaires. Imaginez une balle qui rebondit : elle part de haut (`0%`), touche le sol (`50%`), puis remonte un peu (`75%`) avant de se stabiliser (`100%`). Chaque pourcentage est un ordre donné à l’acteur de notre scène (l’élément HTML). Une fois le scénario écrit, il suffit de l’assigner à l’élément avec `animation-name` et de lui donner une durée avec `animation-duration`. Le navigateur se charge alors de jouer la scène, en calculant toutes les images intermédiaires pour créer un mouvement fluide entre vos points clés.

Penser en pourcentages, c’est donc cesser de voir une animation comme un simple « changement » pour la concevoir comme une véritable histoire avec un début, un milieu et une fin.

Contrôlez votre animation : le guide complet des propriétés `animation-*`

Écrire le scénario avec `@keyframes` n’est que la première étape. Un réalisateur sur un plateau dispose de tout un arsenal d’outils pour dicter comment la scène doit être jouée : à quel rythme, après quel délai, si elle doit se répéter… En CSS, votre plateau de tournage, c’est l’ensemble des propriétés commençant par `animation-*`. Elles sont votre banc de montage virtuel et vous donnent un contrôle total sur le déroulement de l’animation.

Ces propriétés vous permettent de moduler chaque aspect de votre séquence. Vous pouvez définir la durée totale, ajouter un temps mort avant que l’action ne commence, décider du nombre de répétitions (une seule fois, trois fois, ou même à l’infini pour créer une boucle), et même mettre l’animation en pause. L’illustration suivante schématise ce banc de montage où chaque propriété est un curseur à votre disposition.

Banc de montage virtuel montrant les différentes propriétés d'animation CSS comme des curseurs de contrôle

L’une des commandes les plus importantes est la fonction de timing (`animation-timing-function`), qui définit le rythme émotionnel de la scène. Un mouvement `linear` sera mécanique et constant, tandis qu’un `ease-in-out` simulera une accélération puis une décélération, un mouvement beaucoup plus naturel et organique. Maîtriser ces propriétés, c’est passer du statut de simple codeur à celui de véritable chef d’orchestre de l’interface.

Le tableau suivant, inspiré d’une documentation de référence sur les animations CSS, résume les commandes essentielles de votre banc de montage et leur métaphore cinématique :

Les propriétés animation-* et leurs effets
Propriété Fonction Valeurs courantes Métaphore cinématique
animation-duration Durée totale de l’animation 1s, 300ms, 2s Durée de la séquence filmée
animation-delay Délai avant le début 0s, 0.5s, 1s Top départ du régisseur
animation-timing-function Courbe d’accélération ease, linear, cubic-bezier() Rythme émotionnel de la scène
animation-fill-mode État avant/après animation forwards, backwards, both Pose de l’acteur hors scène
animation-play-state Contrôle lecture/pause running, paused Contrôle du direct

En combinant judicieusement ces outils, vous pouvez transformer une simple séquence en une expérience utilisateur riche et engageante, où chaque mouvement a une intention et une personnalité.

Transition ou Animation ? Le guide pour ne plus jamais hésiter

La confusion entre `transition` et `animation` est fréquente car les deux servent à créer du mouvement. Cependant, leur philosophie est radicalement différente. La meilleure métaphore est celle de l’interrupteur face au film. Une `transition` est un interrupteur : elle gère le passage entre deux états fixes, A et B. L’action est binaire et toujours déclenchée par une interaction (un `:hover`, un `:focus`). C’est parfait pour un changement simple et réactif.

Une `animation` `@keyframes`, elle, est un film. Elle possède son propre scénario, sa propre timeline, et peut se jouer automatiquement au chargement de la page, sans attendre une action de l’utilisateur. Elle n’est pas limitée à deux états ; elle peut en contenir une multitude, créant des séquences narratives complexes. Vous voulez qu’un élément avance, s’arrête, tourne sur lui-même puis change de couleur ? C’est un scénario, donc c’est une tâche pour `@keyframes`.

Il ne s’agit pas de choisir l’un contre l’autre. Un bon réalisateur sait quand utiliser un plan fixe et quand lancer une séquence complexe. De même, un bon développeur sait combiner les deux. Par exemple, un bouton peut avoir une `transition` douce sur sa couleur de fond au survol, tandis que ce même survol déclenche une `animation` en boucle sur une petite icône à l’intérieur du bouton. La transition gère la réaction directe, l’animation ajoute une couche de narration visuelle. Le tableau suivant, qui synthétise les principaux critères de décision entre les deux approches, vous aidera à faire le bon choix à chaque fois.

Tableau de décision : Transition vs @keyframes
Critère Utilisez transition Utilisez @keyframes
Nombre d’états 2 états (A → B) Multiple (A → B → C → …)
Déclencheur Interaction utilisateur (:hover, :focus) Automatique ou programmé
Répétition Non, sauf nouvelle interaction Oui, avec animation-iteration-count
Contrôle timeline Simple (durée uniquement) Complexe (étapes à %)
Métaphore Un interrupteur Un film

Le choix n’est donc plus technique, mais stratégique : avez-vous besoin d’une simple réaction ou d’une véritable histoire ? La réponse à cette question déterminera l’outil à utiliser.

Le meilleur des deux mondes : piloter vos animations @keyframes avec JavaScript

Penser que les `@keyframes` rendent JavaScript inutile pour l’animation est une erreur. Penser que JavaScript est nécessaire pour créer des animations complexes en est une autre. La vérité se situe dans la collaboration : le CSS est le moteur de l’animation, et le JavaScript en est le chef d’orchestre. Son rôle n’est pas de manipuler les styles à 60 images par seconde (ce qui est peu performant), mais de donner le « top départ » au bon moment et de réagir à des événements complexes.

L’approche moderne consiste à définir toutes vos animations (vos « scénarios ») en CSS avec `@keyframes`, puis à utiliser JavaScript pour simplement ajouter ou retirer des classes CSS sur vos éléments. C’est une méthode à la fois performante et facile à maintenir. Par exemple, lorsque l’utilisateur fait défiler la page, vous pouvez utiliser un `IntersectionObserver` en JavaScript pour détecter quand un élément devient visible et, à ce moment précis, lui ajouter la classe `.is-visible` qui déclenche une animation d’apparition définie en CSS.

Cette synergie ouvre des possibilités infinies pour créer des expériences interactives riches :

  • Enchaîner des animations : En écoutant les événements `animationstart` et `animationend`, vous pouvez lancer une seconde animation dès que la première est terminée, créant des chorégraphies complexes.
  • Ajuster les animations en temps réel : Vous pouvez utiliser les variables CSS (custom properties) et les modifier en JavaScript. Imaginez un curseur qui contrôle la `animation-duration` en direct !
  • Créer des animations conditionnelles : Selon une action de l’utilisateur (par exemple, la réponse à un quiz), vous pouvez appliquer différentes classes, et donc déclencher différents scénarios d’animation.
  • Synchroniser plusieurs scènes : En utilisant les promesses et `Promise.all()` avec les événements d’animation, vous pouvez vous assurer que plusieurs éléments ont terminé leur séquence avant de déclencher une action globale.

En laissant le CSS gérer le « comment » de l’animation (le rendu visuel) et JavaScript gérer le « quand » et le « pourquoi » (la logique de déclenchement), vous obtenez le meilleur des deux mondes : la performance du natif et la flexibilité de la programmation.

Les secrets des animations CSS fluides : animer les bonnes propriétés

Un film saccadé est une expérience désagréable. Il en va de même pour une animation web. Pour garantir une fluidité parfaite, digne d’un standard de 60 images par seconde (fps), le secret n’est pas dans la complexité de l’animation, mais dans le choix des propriétés que vous animez. Votre navigateur est comme un studio de cinéma avec deux équipes : une équipe de « décorateurs » (le CPU) et une équipe de « machinistes spécialisés » (le GPU).

Animer des propriétés comme `width`, `height`, `margin`, `top` ou `left` revient à demander aux décorateurs (CPU) de redessiner et recalculer toute la mise en page à chaque image. C’est un travail lourd qui provoque des saccades. En revanche, animer les propriétés `transform` (pour la position, la rotation, l’échelle) et `opacity` (pour la visibilité) est différent. Ces tâches sont déléguées directement aux machinistes spécialisés (GPU), qui travaillent sur un calque séparé, sans perturber le reste de la scène. Le résultat est une fluidité parfaite. Des analyses de performance détaillées montrent que les animations utilisant transform et opacity peuvent atteindre 60fps constant, contre à peine 10-20fps pour les autres.

Comparaison visuelle entre GPU et CPU représentés comme machiniste et metteur en scène dans un théâtre

Penser « performance », c’est donc penser « GPU ». Au lieu d’animer la propriété `left` pour déplacer un objet, utilisez `transform: translateX()`. Au lieu de le faire disparaître en animant sa `height` à 0, utilisez `opacity: 0`. C’est un changement de paradigme qui a un impact colossal sur l’expérience utilisateur, surtout sur les appareils mobiles.

Checklist pour des animations performantes

  1. Prioriser les bonnes propriétés : Privilégiez toujours `transform` et `opacity` (accélérées par le GPU) plutôt que `width`, `height`, `margin`, ou `top`/`left`.
  2. Utiliser `will-change` avec parcimonie : Appliquez cette propriété pour indiquer au navigateur qu’un élément va être animé, mais uniquement sur les éléments qui changent fréquemment pour ne pas surcharger la mémoire.
  3. Viser le bon timing : Ciblez des durées d’animation comprises entre 200 et 300ms pour une perception fluide et naturelle.
  4. Forcer l’accélération GPU : Si une animation saccade, appliquez `transform: translateZ(0)` ou `translate3d(0,0,0)` sur l’élément. Cela le promeut sur son propre calque et force le GPU à le prendre en charge.
  5. Tester et mesurer : Utilisez l’onglet « Performance » des outils de développement de Chrome pour enregistrer vos animations et identifier les goulots d’étranglement (« bottlenecks ») qui causent des baisses de framerate.

Le choix des propriétés à animer n’est pas un détail technique, c’est la décision la plus importante que vous prendrez en tant que réalisateur d’animations pour garantir un spectacle impeccable.

L’ordre des transformations compte : le secret pour des animations complexes maîtrisées

Lorsque vous commencez à enchaîner plusieurs transformations sur un même élément (une rotation, puis une translation, puis une mise à l’échelle), vous entrez dans le domaine de la chorégraphie de précision. Et comme en danse, l’ordre des mouvements change tout. Appliquer `transform: rotate(45deg) translateX(100px)` ne produira pas du tout le même résultat visuel que `transform: translateX(100px) rotate(45deg)`. C’est le secret le mieux gardé des animations complexes.

Dans le premier cas, l’élément tourne d’abord de 45 degrés sur son axe, PUIS se déplace de 100px le long de son NOUVEL axe (qui est maintenant incliné). Dans le second cas, l’élément se déplace d’abord de 100px vers la droite, PUIS il tourne de 45 degrés sur son nouveau centre. Cette subtilité est la clé pour maîtriser des effets de type « marionnette » ou des animations mécaniques complexes. L’ordre des fonctions dans la propriété `transform` est lu de gauche à droite, mais chaque transformation s’applique au résultat de la précédente.

Un autre point crucial est le `transform-origin`, qui définit le point de pivot de la transformation. Par défaut, c’est le centre de l’élément (`50% 50%`). Mais si vous le changez pour `0 0` (le coin supérieur gauche), une rotation créera un effet de balancier, comme une porte qui pivote sur ses gonds. En combinant un `transform-origin` bien choisi avec un ordre de transformations réfléchi, vous pouvez créer des mouvements d’une richesse et d’une précision extrêmes, impossibles à obtenir autrement.

Expérimenter avec l’ordre de ces fonctions et le point d’origine est le meilleur moyen de développer une intuition de « physicien de l’animation » et de prédire le comportement de vos éléments.

L’effet de « bordure qui se dessine » : un pas-à-pas pour une animation élégante

Mettons maintenant en pratique notre rôle de réalisateur avec un scénario concret et très populaire : l’animation d’une bordure qui semble se dessiner autour d’un élément au survol. Cet effet élégant est un parfait exemple de scénario en plusieurs actes, impossible à réaliser avec une simple `transition`. Pour y parvenir, nous allons utiliser des pseudo-éléments (`::before` et `::after`) comme acteurs secondaires de notre scène.

Le principe est de créer quatre lignes fines (les pseudo-éléments) positionnées aux quatre coins de notre élément principal, initialement de taille nulle. Notre animation `@keyframes` va ensuite les faire grandir tour à tour pour simuler un tracé continu. C’est un véritable ballet chorégraphié en quatre temps, où chaque acteur entre en scène au bon moment. La beauté de cette technique est qu’elle n’affecte pas la mise en page et reste très performante.

Voici le scénario décomposé en quatre actes, comme un plan de tournage détaillé :

  • Acte 1 (0% à 25%) : Le premier acteur, le pseudo-élément `::before`, est positionné en haut à gauche. On anime sa propriété `width` de 0% à 100%. La ligne du haut se dessine.
  • Acte 2 (25% à 50%) : Le deuxième acteur, le pseudo-élément `::after`, est en haut à droite. On anime sa `height` de 0% à 100%. La ligne de droite apparaît dans la continuité.
  • Acte 3 (50% à 75%) : Il nous faut deux autres acteurs. Nous créons un second `::before` et `::after` via un conteneur. Le troisième acteur, positionné en bas à droite, voit sa `width` animée de 100% à 0% (en partant de la droite). La ligne du bas se dessine.
  • Acte 4 (75% à 100%) : Le dernier acteur, en bas à gauche, voit sa `height` animée de 100% à 0%. La ligne de gauche se dessine, fermant le cadre.

En utilisant des variables CSS pour la couleur, l’épaisseur et la vitesse, ce composant devient entièrement réutilisable et personnalisable, une véritable pièce maîtresse dans votre bibliothèque d’effets spéciaux.

À retenir

  • Pensez en timeline : une animation est un scénario avec des étapes clés (0%, 25%, 100%), pas un simple changement d’état.
  • Priorisez la performance : n’animez que `transform` et `opacity` pour garantir une fluidité à 60fps en exploitant l’accélération matérielle (GPU).
  • L’ordre compte : `rotate()` puis `translateX()` n’est pas la même chose que `translateX()` puis `rotate()`. L’ordre des transformations est la clé des animations complexes.

La magie de `transform` : déplacez vos éléments sans casser votre mise en page

Nous avons établi que la propriété `transform` est la star de la performance. Mais sa magie ne s’arrête pas là. Son plus grand pouvoir est sa capacité à déplacer, faire pivoter ou mettre à l’échelle un élément sans affecter le flux du document. C’est un concept fondamental. Lorsque vous modifiez la position d’un élément avec `top` ou `margin`, le navigateur doit recalculer la position de tous les éléments environnants. C’est ce qu’on appelle un « reflow » ou « layout shift », une opération extrêmement coûteuse qui provoque des saccades.

La propriété `transform`, elle, agit sur un autre plan. Elle déplace l’élément visuellement sur son propre calque de composition, après que la mise en page a été calculée. Pour le navigateur, l’élément est toujours à sa place d’origine. Les autres éléments ne bougent pas. C’est comme si vous déplaciez un fantôme : il bouge, mais ne bouscule personne. Cette dissociation est la raison pour laquelle les animations `transform` sont si fluides. C’est particulièrement visible sur les appareils mobiles, où les ressources CPU sont limitées. D’après des recommandations pour les animations cross-browser, utiliser `transform` et `opacity` sur mobile peut réduire la consommation CPU jusqu’à 70% par rapport à l’animation des propriétés de position ou de dimension.

Un exemple parfait de cette magie est la création d’un menu « off-canvas ». Animer son apparition avec `left: 0` serait un désastre pour la performance, car tout le contenu de la page serait « poussé » à chaque image. La bonne méthode est de le positionner hors de l’écran avec `transform: translateX(-100%)` et de l’animer vers `transform: translateX(0)`. Le menu glisse par-dessus la page sans jamais la perturber, garantissant une ouverture et une fermeture instantanées et fluides, même sur des téléphones d’entrée de gamme.

Pour intégrer cette pratique dans tous vos projets, il est crucial de bien comprendre la magie de la propriété transform.

Maintenant que vous avez les clés pour penser en réalisateur, l’étape suivante est simple : ouvrez votre éditeur de code, choisissez un élément et écrivez votre premier scénario d’animation. Commencez petit, expérimentez avec le timing, et donnez vie à vos interfaces.

Rédigé par Léa Moreau, Léa Moreau est une développeuse front-end et motion designer avec 8 ans d'expérience dans la création d'interfaces web interactives. Elle est spécialisée dans l'art de transformer des pages statiques en expériences immersives grâce aux animations et aux filtres CSS.