Blanche
Blanche Agency

Blanche · Studio

© 2026

Les animations CSS natives au défilement sont là — Il est temps de se débarrasser de votre bibliothèque JavaScript
Retour au blog
Développement WebOptimisation des performancesConception de mouvement30 juin 2026·9 min de lecture

Les animations CSS natives au défilement sont là — Il est temps de se débarrasser de votre bibliothèque JavaScript

Les animations pilotées par le défilement sont désormais une fonctionnalité CSS de premier plan dans les navigateurs modernes — et la plupart des équipes continuent à embarquer 40 ko de JavaScript par pure habitude. Voici pourquoi il faut que ça change, et comment effectuer la transition.

L'habitude des bibliothèques dont on n'arrive pas à se débarrasser

Soyons honnêtes : la dernière fois qu'un designer vous a remis une animation de révélation au défilement, combien de temps s'est-il écoulé avant que vous tapiez npm install gsap ? Pour la plupart des équipes frontend, ce réflexe est tellement ancré que personne ne le remet en question. GSAP est excellent. Framer Motion est excellent. Mais on a pris l'habitude de sortir l'artillerie lourde pour enfoncer des punaises, alors que le navigateur construisait tranquillement un meilleur outil.

En 2025, les animations pilotées par le défilement font partie intégrante de la spécification CSS — et la prise en charge par les navigateurs a franchi un seuil qui rend leur usage en production non seulement faisable, mais qu'il serait franchement irresponsable d'ignorer. Ce n'est pas un autre article de curiosité du genre « CSS sait faire X maintenant ». C'est un défi direct : auditez ce que vous livrez, car une bonne partie de votre JavaScript d'animation peut être supprimée dès aujourd'hui.


Ce que les animations CSS au défilement vous offrent concrètement

La spécification Scroll-driven Animations introduit deux mécanismes fondamentaux : les timelines de défilement et les timelines de vue. Ils vous permettent de lier n'importe quelle animation CSS @keyframes à la progression du défilement plutôt qu'au temps — sans écouteurs d'événements, sans boucles requestAnimationFrame, sans recalcul de mise en page.

@keyframes fade-in-up {
  from { opacity: 0; transform: translateY(40px); }
  to   { opacity: 1; transform: translateY(0); }
}

.card {
  animation: fade-in-up linear both;
  animation-timeline: view();
  animation-range: entry 0% entry 40%;
}

C'est tout. Cet élément .card s'animera désormais à son entrée dans la fenêtre d'affichage — sans IntersectionObserver, sans gestionnaire de défilement, sans bibliothèque. Le navigateur gère tout au niveau du compositeur.

Les deux types de timelines à connaître

  • scroll() — lie la progression de l'animation à la distance de défilement totale d'un conteneur. Parfait pour les barres de progression et les décalages en parallaxe.
  • view() — lie la progression de l'animation à la position d'un élément dans la fenêtre d'affichage. Parfait pour les animations d'entrée/sortie et les effets de révélation.

Vous pouvez également nommer les timelines avec scroll-timeline-name et view-timeline-name pour orchestrer des animations entre différents éléments — une capacité qui nécessitait auparavant du JavaScript pour être coordonnée.

Prise en charge par les navigateurs en 2025 : ce que les lacunes signifient réellement

Chrome et Edge disposent d'une prise en charge complète depuis la version 115. Firefox a livré une prise en charge complète à partir de la version 110. Safari fait figure d'exception — une prise en charge partielle est arrivée dans Safari 18.2 (fin 2024), mais animation-range et les timelines nommées restent incohérents.

La prise en charge globale s'établit autour de 84 à 87 % des utilisateurs selon la manière dont vous analysez les données. Dans la plupart des contextes d'agence — notamment les SaaS B2B, les outils pour développeurs ou les portfolios créatifs — votre distribution de navigateurs penche suffisamment vers Chrome et Firefox pour que ce chiffre soit encore plus élevé en pratique.

L'essentiel à retenir : l'absence de prise en charge dans Safari ne signifie pas que vos animations se cassent. Cela signifie qu'elles ne se lancent pas. Avec une amélioration progressive appropriée (abordée ci-dessous), c'est un repli tout à fait acceptable.


Comparatif de performances : natif vs. les grandes bibliothèques JS

C'est là que la conversation devient inconfortable pour les partisans des bibliothèques.

ScrollTrigger de GSAP fonctionne en écoutant les événements de défilement sur le thread principal et en mettant à jour les styles des éléments via JavaScript. Même avec l'optimisation exceptionnelle de GSAP, vous exécutez toujours de la logique sur le thread principal, déclenchez des recalculs de style et — si vous animez transform ou opacity — naviguez entre les limites des threads.

Les animations CSS natives au défilement s'exécutent entièrement sur le thread compositeur pour les propriétés transform et opacity. Le thread principal n'est jamais impliqué. Ce n'est pas une amélioration marginale.

« Les animations sur le thread compositeur ne peuvent pas être perturbées par une exécution JavaScript intensive sur le thread principal. Quand votre application fait un vrai travail — analyse de données, rendu de composants — les animations de défilement natives continuent de jouer sans accroc. Les animations au défilement pilotées par JS, non. »

Dans des profilages réels avec Chrome DevTools, une page avec 12 révélations de cartes au défilement utilisant des timelines view() affiche zéro travail d'animation de défilement sur le thread principal. L'implémentation GSAP équivalente affiche des pics constants de 2 à 4 ms sur le thread principal par image de défilement — pas catastrophique, mais cumulatif, et qui passe mal à l'échelle avec la complexité.

Le whileInView de Framer Motion est encore plus lourd. Il passe par le cycle de réconciliation de React et utilise des callbacks IntersectionObserver pour déclencher des changements d'état. Sur les appareils Android bas de gamme, ce schéma est visiblement saccadé d'une façon que le CSS natif ne l'est tout simplement pas.

Comparaison de la taille des bundles :

  • GSAP core + ScrollTrigger : ~45 ko minifié + gzippé
  • Framer Motion (complet) : ~170 ko
  • Animations CSS natives au défilement : 0 ko

Ce n'est pas rhétorique. Zéro octet. Pas d'import, pas d'initialisation, aucune dépendance à auditer.


Cinq modèles concrets que vous pouvez livrer cette semaine

1. Indicateur de progression du défilement

@keyframes grow-bar {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.progress-bar {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 4px;
  background: #6c63ff;
  transform-origin: left;
  animation: grow-bar linear;
  animation-timeline: scroll(root);
}

Celui-ci nécessitait autrefois ~20 lignes de JavaScript. Maintenant, ce sont six déclarations CSS.

2. Révélations de sections en cascade

Utilisez animation-delay avec les timelines view() pour créer des effets d'entrée décalés sans orchestration JavaScript :

.feature-card {
  animation: fade-in-up linear both;
  animation-timeline: view();
  animation-range: entry 10% entry 50%;
}
.feature-card:nth-child(2) { animation-delay: 0.1s; }
.feature-card:nth-child(3) { animation-delay: 0.2s; }

3. Décalage en parallaxe de l'arrière-plan

.hero {
  animation: parallax-shift linear;
  animation-timeline: scroll(root);
}
@keyframes parallax-shift {
  from { background-position: 50% 0%; }
  to   { background-position: 50% 40%; }
}

4. Compteur de section épinglé

Les timelines de vue nommées permettent à un élément parent de piloter les animations de ses enfants — idéal pour les barres latérales épinglées qui réagissent à la progression du défilement de leur section :

.section {
  view-timeline-name: --section-progress;
  view-timeline-axis: block;
}

.sticky-label {
  animation: label-fade linear both;
  animation-timeline: --section-progress;
  animation-range: contain;
}

5. Animations de sortie

La plupart des bibliothèques JS gèrent les animations de sortie. view() aussi :

.card {
  animation: reveal-and-fade linear both;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}
@keyframes reveal-and-fade {
  0%   { opacity: 0; transform: scale(0.9); }
  20%  { opacity: 1; transform: scale(1); }
  80%  { opacity: 1; }
  100% { opacity: 0; }
}

Les cas limites où les bibliothèques JS gardent l'avantage

L'honnêteté s'impose ici. Il existe de véritables scénarios où l'approche native montre ses limites :

  • Animations basées sur la physique : les simulations de ressort, les courbes de momentum et les interactions basées sur la vélocité n'ont pas d'équivalent en CSS. GSAP et des bibliothèques comme react-spring règnent en maîtres sur ce terrain.
  • Séquençage complexe avec logique conditionnelle : si votre animation au défilement doit se ramifier en fonction de l'état utilisateur, de données ou des capacités de l'appareil — c'est du ressort de JavaScript.
  • Détournement du défilement et mécaniques personnalisées : les moteurs de défilement virtuel (Lenis, Locomotive) qui court-circuitent le défilement natif pour créer des expériences fluides et contrôlées ne peuvent pas être répliqués en CSS.
  • Exigences de parité avec Safari : si votre contrat impose une cohérence pixel parfaite sur tous les navigateurs, Safari ≤ 18.1 inclus, vous aurez besoin d'un polyfill ou d'une stratégie de repli en JavaScript. Le polyfill officiel scroll-timeline de Google fonctionne, mais réintroduit du poids.
  • Scrubbing précis de timeline : si les designers ont besoin de parcourir les animations en avant et en arrière avec un contrôle précis (pensez aux sites de narration interactive primés), l'API timeline de GSAP est genuinement plus expressive.

Notablement absent de cette liste : les révélations basiques au défilement, la parallaxe, les indicateurs de progression et les animations d'entrée — qui représentent la grande majorité du travail d'animation au défilement dans un projet d'agence typique.


Amélioration progressive : livrer des animations CSS natives en toute sécurité dès aujourd'hui

La bonne approche n'est pas « attendre une prise en charge à 100 % des navigateurs ». La bonne approche est une requête de fonctionnalité propre :

/* État de base : visible, sans animation */
.card {
  opacity: 1;
  transform: none;
}

/* Amélioré : animation uniquement si pris en charge */
@supports (animation-timeline: view()) {
  .card {
    opacity: 0;
    animation: fade-in-up linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 40%;
  }
}

Les navigateurs non pris en charge voient immédiatement l'état final — le contenu est toujours accessible. Les navigateurs pris en charge bénéficient de l'expérience enrichie. Pas de poids de polyfill, pas de bibliothèque de détection, pas de JavaScript requis.

C'est l'amélioration progressive telle qu'elle a toujours été conçue : une base de code unique, des capacités en couches, sans compromis sur l'accessibilité de base.


Écrire moins de code est une fonctionnalité, pas un compromis

Il existe un piège psychologique dans le développement frontend où la complexité est perçue comme un signe de compétence. Livrer une timeline GSAP personnalisée avec des courbes d'accélération sur mesure donne l'impression d'être plus professionnel que six lignes de CSS. Ce n'est pas le cas.

Le meilleur code est celui que vous n'avez pas à écrire, maintenir, mettre à jour, auditer pour des vulnérabilités de sécurité, ou expliquer au prochain développeur sur le projet. Les fonctionnalités natives du navigateur viennent avec une documentation gratuite, une optimisation des performances gratuite, et une longévité garantie.

La spécification des animations au défilement est stable, la prise en charge des navigateurs est viable en production dès maintenant, et les avantages en termes de performances sont réels. Le seul argument restant pour recourir par défaut à une bibliothèque JavaScript pour les animations au défilement, c'est l'inertie — et ce n'est pas un argument.

Auditez votre prochain projet. Listez chaque animation déclenchée par le défilement. Demandez-vous lesquelles ont genuinement besoin de JavaScript. Cette liste sera plus courte que vous ne le pensez — et la ramener à zéro devrait être l'objectif.

L'habitude des bibliothèques est difficile à briser. Brisez-la quand même.