Les animations pilotées par le défilement reposent sur trois propriétés CSS : animation-timeline, scroll-timeline et view-timeline. Prises en charge par Chrome et Edge depuis 2023, elles viennent d’achever leur parcours de compatibilité en 2026 avec leur arrivée dans Firefox (version 159) et Safari (version 26.0), pour une couverture mondiale d’environ 87,8 % des navigateurs. Il devient possible de synchroniser une animation sur la position de défilement sans écouter un seul événement scroll en JavaScript.
Deux timelines, un seul principe
Une timeline de défilement remplace le temps par une progression de 0 % à 100 %. Deux variantes existent. La scroll progress timeline (scroll-timeline) mesure la progression du défilement à l’intérieur d’un conteneur, du haut vers le bas. La view progress timeline (view-timeline) mesure, elle, la progression d’un élément précis à travers la zone visible de l’écran : 0 % quand il entre dans le viewport, 100 % quand il en sort.
Mettre en œuvre scroll-timeline et view-timeline
Une barre de progression de lecture
Le cas le plus courant est la barre de progression d’un article, qui se remplit au fil du défilement de la page.
<div class="progress-track">
<div class="progress-bar"></div>
</div>:root {
timeline-scope: --page-scroll;
}
html {
scroll-timeline: --page-scroll block;
}
.progress-bar {
animation: remplir linear;
animation-timeline: --page-scroll;
}
@keyframes remplir {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}Aucun gestionnaire d’événement, aucun calcul de pourcentage à la main : le moteur de rendu interpole directement les propriétés animées en fonction de la progression du défilement.
Révéler une carte à l’arrivée dans le viewport
Pour des effets d’apparition au défilement (fondu, translation), view-timeline cible directement l’élément à animer plutôt que le conteneur qui défile.
.carte {
view-timeline-name: --apparition-carte;
view-timeline-axis: block;
animation: apparaitre linear;
animation-timeline: --apparition-carte;
animation-range: entry 10% cover 40%;
}
@keyframes apparaitre {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: translateY(0); }
}animation-range borne la plage sur laquelle l’animation se joue : ici, elle démarre quand la carte a parcouru 10 % de son entrée dans le viewport et se termine à 40 % de sa traversée complète, pour éviter un effet qui se déclenche trop tôt ou se termine trop tard.
Une timeline de défilement n’écoute aucun événement : la progression est calculée directement dans le pipeline de style du moteur de rendu, sans repasser par le thread principal JavaScript.
Compatibilité, repli et débogage
Compatibilité enfin réelle en 2026
| Navigateur | Version minimale | Arrivée |
|---|---|---|
| Chrome | 115 | Juillet 2023 |
| Edge | 115 | Juillet 2023 |
| Safari | 26.0 | 2026 |
| Firefox | 159 | 2026 |
Le support de Firefox et Safari n’est arrivé que cette année : les trois propriétés étaient jusque-là réservées à des effets strictement progressifs, repliés sans animation sur les navigateurs non couverts.
Déboguer une timeline dans les outils de développement
Chrome et Edge affichent les timelines de défilement actives directement dans le panneau Animations des outils de développement : chaque timeline apparaît avec sa plage de progression actuelle, consultable en faisant défiler la page pendant que le panneau reste ouvert. C’est le moyen le plus rapide de vérifier qu’un animation-range démarre et se termine au bon endroit, plutôt que de deviner les valeurs par essais successifs dans la feuille de style. Firefox expose une inspection comparable depuis l’arrivée du support dans sa version 159.
Repli pour les navigateurs non couverts
Pour les audiences qui comptent encore une part de navigateurs anciens, une requête de fonctionnalité évite de livrer un contenu figé par erreur de style plutôt que par absence d’animation :
@supports (animation-timeline: works) {
.carte {
opacity: 0;
}
}Sans ce test, un élément dont l’état initial dépend de l’animation (ici une opacité à 0 avant apparition) resterait invisible sur un navigateur qui ne joue jamais l’animation.
Accessibilité, carrousel et performances
Respecter la préférence de mouvement réduit
@media (prefers-reduced-motion: reduce) {
.carte {
animation: none;
opacity: 1;
transform: none;
}
}Associer scroll-snap et view-timeline pour un carrousel guidé
Les deux mécanismes se combinent bien : un conteneur en scroll-snap-type impose un arrêt net sur chaque diapositive, tandis qu’une view-timeline posée sur chaque élément du carrousel pilote son échelle ou son opacité pendant qu’il traverse la zone centrale.
.carrousel {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.carrousel > * {
scroll-snap-align: center;
view-timeline-name: --diapo;
view-timeline-axis: inline;
animation: reduire-aux-bords linear;
animation-timeline: --diapo;
animation-range: cover 0% cover 100%;
}
@keyframes reduire-aux-bords {
0%, 100% { transform: scale(0.85); opacity: 0.5; }
50% { transform: scale(1); opacity: 1; }
}Le résultat : la diapositive centrée grossit légèrement et les voisines se réduisent, sans qu’aucun script ne recalcule la position de défilement à chaque image.
Incidence sur les performances
Ces animations s’exécutent dans le pipeline de style du moteur de rendu plutôt que dans une boucle requestAnimationFrame pilotée par le thread principal. Concrètement, un défilement rapide ne fait plus concurrence au JavaScript de la page pour les mêmes ressources CPU, ce qui réduit le risque de saccades sur les appareils d’entrée de gamme. La contrepartie : seules les propriétés qui peuvent être animées par composition (transform, opacity notamment) restent fluides sans à-coups ; animer des propriétés qui déclenchent une mise en page (comme width ou top) reste coûteux, timeline CSS ou non.
Cas d’usage côté production
Au-delà de la barre de progression, des apparitions de cartes et du carrousel ci-dessus, le même mécanisme sert à rétrécir un en-tête de page au fil du défilement ou à faire glisser une image en effet de parallaxe léger. Dans tous les cas, l’animation reste déclarative et ne dépend plus d’une bibliothèque JavaScript dédiée au défilement, à la différence des approches encore nécessaires pour des transitions de page complètes comme celles détaillées dans notre article sur les View Transitions.
Ce mécanisme complète utilement les techniques déjà disponibles sans JavaScript, du positionnement d’ancrage CSS pour les menus et infobulles aux container queries pour les composants adaptatifs : la mise en page et l’interaction continuent de migrer du JavaScript vers des mécanismes déclaratifs pris en charge nativement par le moteur de rendu.
Ce qu’il faut retenir
Avec l’arrivée de Firefox 159 et Safari 26, les animations pilotées par le défilement couvrent désormais l’essentiel du parc de navigateurs et peuvent passer d’une curiosité expérimentale à un outil de production. Une requête @supports en repli et le respect de prefers-reduced-motion restent les deux précautions qui évitent qu’une amélioration visuelle ne se transforme en régression d’accessibilité.
J’ai remplacé cette année une bibliothèque JavaScript de parallaxe par ces trois propriétés sur un projet client, pour un gain de fluidité net sur mobile et une ligne de dépendance en moins dans le bundle. Mon seul regret : la documentation reste éparpillée entre MDN et les billets de blog Chrome, et il faut tester soi-même chaque plage d’animation-range au pifomètre avant de trouver le bon réglage. — Simon Janvier
Pour aller plus loin : la référence CSS Scroll-driven Animations sur MDN.
