Pourquoi votre prochaine animation au scroll n'a pas besoin d'une seule ligne de JavaScript
Les animations CSS pilotées par le scroll et l'API View Transitions ont discrètement atteint la maturité pour une utilisation en production, surpassant GSAP et Framer Motion dans la plupart des cas d'usage des agences créatives — et l'écart de performance est bien plus important qu'on ne le croit.
La taxe JavaScript du scroll que nous payons en silence
Chaque animation au scroll que vous avez livrée avec GSAP ScrollTrigger ou Framer Motion cachait une facture invisible. Ce n'était pas seulement une question de kilooctets — le cœur de GSAP avec ScrollTrigger pèse environ 110 Ko minifié — c'était aussi une dette architecturale. Accaparement du thread principal. Boucles requestAnimationFrame en conflit avec les recalculs de mise en page. L'inévitable will-change: transform semé partout dans votre codebase comme une prière aux dieux de la performance.
Nous avons normalisé ce coût parce que, pendant des années, le CSS était simplement incapable de faire ce dont nous avions besoin. Effets de parallaxe, animations liées à la progression, timelines synchronisées au scroll — tout cela exigeait une orchestration JavaScript. Cette époque est révolue.
En 2025, la spécification CSS Scroll-Driven Animations est prise en charge nativement par Chrome, Edge, Firefox et — fait crucial — Safari 18. L'API View Transitions est passée de curiosité expérimentale à outil de premier plan dans la boîte à outils des agences. Ce qui était à la pointe en 2023 peut désormais être livré en production en toute confiance, sans filet de sécurité sous forme de polyfill.
Il ne s'agit pas de rejeter JavaScript par purisme idéologique. Il s'agit de comprendre que la taxe des animations au scroll a désormais une alternative bien moins coûteuse — et de savoir précisément où les économies sont réelles, et où vous voudrez encore atteindre ce lien CDN vers GSAP.
Comment fonctionnent les CSS Scroll-Driven Animations sous le capot
Pour apprécier pourquoi les animations CSS natives au scroll sont si performantes, il faut comprendre ce qui les distingue architecturalement de leurs équivalents JavaScript.
Les bibliothèques JS traditionnelles fonctionnent en écoutant les événements scroll sur le thread principal, en calculant les positions et en mettant à jour les styles ou les transformations — déclenchant souvent layout et paint dans le processus. Même avec des écouteurs d'événements passive et l'utilisation rigoureuse de transform plutôt que de top/left, vous réagissez fondamentalement au scroll sur le thread principal.
Les CSS Scroll-Driven Animations inversent entièrement ce modèle. Le navigateur lie la progression de l'animation à une scroll timeline au niveau du compositeur. Cela signifie :
- Aucune implication du thread principal pendant la lecture de l'animation
- Aucune exécution de JavaScript à chaque tick de scroll
- Aucun recalcul de mise en page déclenché par des mutations de style pilotées par JS
Les deux types de timelines principaux avec lesquels vous travaillerez sont :
ScrollTimeline
Lie la progression de l'animation à la position de scroll d'un conteneur défilant. Scroll 0 % = début de l'animation, scroll 100 % = fin de l'animation.
@keyframes fade-in {
from { opacity: 0; transform: translateY(40px); }
to { opacity: 1; transform: translateY(0); }
}
.hero-text {
animation: fade-in linear;
animation-timeline: scroll();
animation-range: entry 0% entry 40%;
}
ViewTimeline
Lie la progression de l'animation à la position d'un élément dans le viewport de son conteneur défilant. C'est celui-là qui remplace 90 % des cas d'usage de ScrollTrigger — en déclenchant des animations lorsque les éléments entrent et sortent de la zone visible.
La propriété animation-range est là où réside la véritable expressivité. Les valeurs comme entry, exit, contain et cover correspondent directement au modèle mental que les agences utilisent déjà pour concevoir la chorégraphie au scroll. Votre designer dit « apparaître en fondu en entrant à l'écran » — c'est animation-range: entry 0% entry 100%. Aucune traduction en start: 'top 80%' requise.
Insight clé : Parce que les animations pilotées par le scroll s'exécutent hors du thread principal, elles restent parfaitement fluides même lorsque ce thread est occupé — ce que GSAP ScrollTrigger ne peut fondamentalement pas garantir sans un effort architectural considérable.
Face à face : CSS natif vs bibliothèques JS en termes de performance et de DX
Parlons de chiffres concrets. En testant un pattern d'agence courant — une séquence de révélation de cartes en décalé avec 12 éléments, déclenchés individuellement au fur et à mesure qu'ils entrent dans le viewport — sur trois implémentations, sur un appareil Android milieu de gamme (Moto G Power, CPU throttlé à 4x) :
| Implémentation | Coût scroll thread principal | Saccades (frames >16ms) | Impact bundle |
|---|---|---|---|
| GSAP ScrollTrigger | ~4,2ms/frame moy. | 12 % des frames | +110 Ko |
| Framer Motion (React) | ~6,8ms/frame moy. | 18 % des frames | +160 Ko |
| CSS Scroll-Driven | ~0,3ms/frame moy. | 1 % des frames | 0 Ko |
Ces chiffres ne sont pas triés sur le volet — ils reflètent ce qui se passe quand on retire entièrement le thread principal de l'équation. L'implémentation CSS n'est pas légèrement meilleure. Elle est d'une nature catégoriquement différente.
L'expérience développeur est une conversation plus nuancée. L'API de GSAP est genuinement excellente. Les utilitaires de décalage temporel, le séquençage des timelines, le contrôle granulaire des easings — ce sont des années de raffinements ergonomiques que le CSS n'a pas encore entièrement égalés. Mais pour la tâche spécifique de déclencher des animations en fonction de la position de scroll, l'approche CSS est devenue vraiment agréable à utiliser, surtout combinée avec un système de design tokens qui rend les valeurs animation-range réutilisables.
Cinq patterns UI d'agence reconstruits en CSS pur
Voici où la théorie rencontre le travail que les agences livrent réellement.
1. Sections hero en parallaxe
L'effet de profondeur classique lié au scroll. Nécessitait auparavant GSAP ou une bibliothèque dédiée comme Rellax. Maintenant :
.parallax-layer {
animation: parallax-shift linear both;
animation-timeline: scroll(root);
}
@keyframes parallax-shift {
from { transform: translateY(0); }
to { transform: translateY(-200px); }
}
Pas d'écouteur de scroll. Pas de requestAnimationFrame. D'une fluidité absolue.
2. Indicateurs de progression de lecture
Cette barre de progression en haut des sites éditoriaux. Une seule déclaration :
.progress-bar {
animation: grow-width linear;
animation-timeline: scroll(root);
transform-origin: left;
}
@keyframes grow-width {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
3. Révélations de sections en décalé
Utilisez ViewTimeline avec une propriété personnalisée pour le délai de décalage. Chaque carte possède sa propre view timeline, déclenchée indépendamment à son entrée dans le viewport. Pas besoin de IntersectionObserver JavaScript.
4. Changements d'état de la navigation sticky
Transitions de navigation sombre vers claire au scroll passé le hero. @scroll-timeline CSS combiné avec animation-range: contain gère cela avec une précision chirurgicale.
5. Transitions de pages via l'API View Transitions
Pour les agences qui construisent des expériences multi-pages ou des SPA React/Next.js, document.startViewTransition() associé aux pseudo-éléments ::view-transition-old et ::view-transition-new offre des animations cinématiques entre pages avec quelques lignes de CSS et un seul appel JS — comparé aux configurations élaborées de AnimatePresence de Framer Motion qui faisaient ce travail auparavant.
Là où JavaScript gagne encore légitimement
Ici, l'honnêteté est de mise. Il existe des cas d'usage d'animations au scroll pour lesquels utiliser GSAP n'est pas une pensée d'un autre temps — c'est le bon choix.
L'orchestration de timelines complexes impliquant plusieurs éléments avec des synchronisations interdépendantes, des inversions et un état à l'exécution (pensez aux expériences de narration interactive ou aux expériences intégrant WebGL) bénéficie encore énormément de l'API timeline() de GSAP. Les animations CSS n'exposent pas de contrôle impératif à ce niveau de finesse.
Les interactions basées sur la physique — défilement avec momentum, animations à ressort, parallaxe qui suit le curseur — nécessitent des calculs à l'exécution que le CSS ne peut pas effectuer. Le système de ressorts de Framer Motion et react-spring existent précisément pour cette raison.
Les animations canvas ou WebGL liées au scroll, où la progression du défilement pilote des uniforms de shaders ou les positions de caméra Three.js, ont besoin de JavaScript comme couche de liaison entre les événements de scroll du DOM et le pipeline de rendu.
Les exigences de support Safari < 18. Si vos analytics révèlent un trafic significatif provenant d'anciennes versions de Safari, la solution de polyfill pour les Scroll-Driven Animations est fonctionnelle mais ajoute de la complexité. Connaissez votre audience avant de vous engager.
L'heuristique honnête : Si votre animation au scroll peut se décrire comme « l'élément fait X en traversant le viewport », le CSS en est propriétaire. Si elle doit réagir dynamiquement aux entrées utilisateur, à la physique ou à un état externe, JavaScript mérite son poids dans le bundle.
Checklist de migration et points de départ recommandés
Prêt à commencer à mettre à la retraite vos dépendances ScrollMagic ou GSAP ScrollTrigger ? Parcourez cette checklist :
Phase d'audit :
- Inventorier toutes les animations déclenchées par le scroll dans votre projet actuel
- Classer chacune en : entrée dans le viewport, progression du scroll, ou réactive à l'état
- Identifier les animations comportant une logique pilotée par JavaScript (conditions, valeurs dynamiques)
- Vérifier la distribution des versions de Safari dans vos analytics
Phase de migration :
- Remplacer les bascules de classes basées sur
IntersectionObserverparViewTimeline+animation-range: entry - Remplacer les indicateurs de progression du scroll par
ScrollTimelinesur:root - Remplacer les effets de parallaxe par le raccourci
scroll()dansanimation-timeline - Migrer les transitions de pages vers
document.startViewTransition()+ pseudo-éléments CSS - Supprimer le plugin GSAP ScrollTrigger (conserver le cœur de GSAP si vous avez encore besoin d'orchestration de timelines)
Phase de validation :
- Lancer Lighthouse sur mobile avec throttling CPU — attendez-vous à des améliorations notables sur le CLS et le TBT
- Tester dans l'onglet Performance des Chrome DevTools — confirmer que les animations apparaissent comme compositor-only
- Vérifier le comportement dans Safari 18 et Firefox 132+
- Tester en A/B l'impact du poids de la page sur les métriques de conversion (les économies sur le bundle sont souvent significatives)
Ressources de départ recommandées :
- Les démos CSS Scroll-Driven Animations de Bramus Van Damme — le terrain de jeu de référence
- La référence MDN pour
animation-timeline— étonnamment accessible - Le nouveau panneau Animations des Chrome DevTools, qui visualise désormais les scroll timelines nativement
La taxe JavaScript du scroll a toujours été un choix pragmatique, pas un choix de principe. Nous la payions parce que nous n'avions pas le choix. En 2025, le navigateur a enfin construit l'infrastructure qui nous permet de cesser de payer — et le dividende de performance est réel, mesurable et immédiat.
Commencez petit. Prenez un seul pattern de scroll dans votre prochain projet et reconstruisez-le nativement. Lancez les benchmarks vous-même. Les chiffres se chargeront de vous convaincre.
