Animations CSS au scroll : le guide complet 2026

18 mars 2026 · 8 min de lecture · CSS

Pendant des années, animer des éléments en fonction du scroll nécessitait du JavaScript : un listener sur l'événement scroll, un calcul de position, et une mise à jour manuelle des propriétés CSS. C'était verbeux, fragile et mauvais pour les performances. En 2026, cette époque est révolue.

Les spécifications CSS Scroll-Driven Animations sont désormais supportées par tous les navigateurs majeurs. Chrome, Firefox, Safari et Edge implémentent tous les propriétés scroll-timeline et view-timeline. Il est temps de les adopter pleinement.

Le principe fondamental

L'idée derrière les animations pilotées par le scroll est élégante : au lieu d'animer un élément en fonction du temps (comme avec @keyframes classiques), on l'anime en fonction de la progression du scroll. L'animation avance quand l'utilisateur scrolle vers le bas, recule quand il scrolle vers le haut.

Deux types de timelines existent :

Scroll Timeline : les bases

Commençons par un exemple simple. Imaginons une barre de progression qui se remplit au fur et à mesure que l'utilisateur scrolle la page :

.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: linear-gradient(90deg, #c084fc, #f472b6);
  transform-origin: left;
  animation: grow-progress linear;
  animation-timeline: scroll();
}

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

C'est tout. Pas de JavaScript. La propriété animation-timeline: scroll() remplace la timeline temporelle par défaut par une timeline de scroll. L'animation avance naturellement avec le défilement de la page.

La fonction scroll() accepte deux paramètres optionnels :

/* Syntaxe complète */
animation-timeline: scroll(<scroller> <axis>);

/* Exemples */
animation-timeline: scroll();           /* root, block */
animation-timeline: scroll(root);       /* root scroller, block axis */
animation-timeline: scroll(nearest);    /* nearest scrollable ancestor */
animation-timeline: scroll(root inline); /* root scroller, inline axis */

View Timeline : animer à l'entrée dans le viewport

La View Timeline est probablement ce que vous utiliserez le plus souvent. Elle permet d'animer un élément au moment où il entre dans le viewport, exactement comme le faisait IntersectionObserver avec du JavaScript.

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

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

La propriété animation-range est cruciale ici. Elle définit la portion de la timeline sur laquelle l'animation se déroule. entry 0% correspond au moment où l'élément commence à entrer dans le viewport, entry 100% correspond au moment où il est complètement visible.

Les ranges disponibles

La spécification définit plusieurs ranges nommées :

/* Fade-in uniquement à l'entrée */
animation-range: entry;

/* Animation pendant toute la visibilité */
animation-range: cover;

/* Animation entre 25% de l'entrée et 75% de la sortie */
animation-range: entry 25% exit 75%;

Timelines nommées

Parfois, vous voulez que l'animation d'un élément soit liée au scroll d'un autre conteneur. C'est là que les timelines nommées interviennent :

.scroll-container {
  overflow-y: auto;
  scroll-timeline-name: --my-scroller;
  scroll-timeline-axis: block;
}

.animated-element {
  animation: slide-in linear both;
  animation-timeline: --my-scroller;
}

@keyframes slide-in {
  from { transform: translateX(-100%); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}

On peut aussi utiliser view-timeline-name pour créer une view timeline nommée, ce qui est utile quand l'élément animé et l'élément observé sont différents.

Cas d'usage concrets

Parallax sans JavaScript

L'effet parallax, longtemps gourmand en JavaScript, devient trivial :

.parallax-bg {
  animation: parallax linear;
  animation-timeline: scroll();
}

@keyframes parallax {
  from { transform: translateY(0); }
  to   { transform: translateY(-30%); }
}

Révéler une galerie d'images

.gallery-item {
  animation: reveal linear both;
  animation-timeline: view();
  animation-range: entry 10% entry 90%;
}

@keyframes reveal {
  from {
    opacity: 0;
    transform: scale(0.9) translateY(20px);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
    filter: blur(0);
  }
}

Header qui se compacte au scroll

.site-header {
  animation: compact-header linear both;
  animation-timeline: scroll();
  animation-range: 0px 200px;
}

@keyframes compact-header {
  from {
    padding-block: 24px;
    background: transparent;
  }
  to {
    padding-block: 8px;
    background: rgba(0, 0, 0, 0.9);
    backdrop-filter: blur(20px);
  }
}

Performances : pourquoi c'est mieux

Les animations pilotées par le scroll en CSS sont fondamentalement plus performantes que leurs équivalents JavaScript pour plusieurs raisons :

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0s !important;
    animation-timeline: none !important;
  }
}

Compatibilité navigateur en 2026

Au moment d'écrire ces lignes (mars 2026), le support est excellent :

Cela signifie que plus de 95% des utilisateurs ont accès à cette fonctionnalité. Pour les navigateurs plus anciens, l'animation ne se déclenche simplement pas : l'élément reste dans son état final, ce qui constitue un fallback gracieux.

Conseils pratiques

Utilisez les animations au scroll avec modération. Un site où tout bouge en permanence fatigue l'utilisateur. Réservez-les aux moments où elles servent véritablement le contenu.

Quelques bonnes pratiques :

  1. Animez des propriétés composites : transform et opacity sont les meilleures candidates. Évitez d'animer width, height ou margin.
  2. Testez sur mobile : le comportement du scroll sur mobile (avec le bounce, les barres d'adresse qui se cachent, etc.) peut affecter vos animations.
  3. Utilisez animation-range : ne faites pas durer l'animation sur toute la timeline. Concentrez-la sur la portion pertinente.
  4. Pensez accessibilité : respectez toujours prefers-reduced-motion.
  5. Combinez avec will-change : si vous animez beaucoup d'éléments simultanément, indiquez au navigateur les propriétés qui vont changer.

Conclusion

Les animations CSS pilotées par le scroll représentent l'une des avancées les plus significatives du CSS ces dernières années. Elles éliminent des centaines de lignes de JavaScript, améliorent les performances et offrent une syntaxe déclarative élégante.

En 2026, il n'y a plus aucune raison d'utiliser un listener scroll pour des animations. Le CSS gère désormais cela nativement, de manière plus performante et plus maintenable. Il est temps de réécrire vos effets de scroll en pur CSS.

Retour au journal

Recevez le digest hebdomadaire.

Un email par semaine. Le meilleur du web design et du développement. Zéro spam, désabonnement en un clic.