Back

Défilement fluide avec scroll-behavior en CSS

Défilement fluide avec scroll-behavior en CSS

Cliquer sur un lien d’ancrage et voir la page sauter instantanément vers une section donne une impression abrupte. Cela désoriente les utilisateurs, rompt le flux de lecture et rend la navigation interne peu soignée. La solution tient en une seule propriété CSS — aucune bibliothèque JavaScript requise.

Points clés à retenir

  • La propriété CSS scroll-behavior: smooth permet un défilement animé pour les liens d’ancrage et les API de défilement programmatique, sans aucun JavaScript.
  • Appliquez-la à l’élément html, et non à body, afin que la propriété se propage correctement à la fenêtre d’affichage.
  • L’accélération et la durée contrôlées par le navigateur ne peuvent pas être personnalisées via CSS — passez à JavaScript uniquement si vous avez besoin d’un contrôle précis.
  • Utilisez scroll-margin-top pour empêcher les en-têtes fixes de masquer les cibles d’ancrage.
  • Encadrez la règle dans une media query prefers-reduced-motion: no-preference pour respecter les préférences d’accessibilité.

Qu’est-ce que scroll-behavior et comment fonctionne-t-il ?

La propriété CSS scroll-behavior contrôle la manière dont un conteneur défilant se déplace lorsque le défilement est déclenché de manière programmatique — par des liens d’ancrage, une navigation par hash, ou des API JavaScript comme window.scrollTo() ou element.scrollIntoView().

Elle accepte deux valeurs :

  • auto — la valeur par défaut. Défile instantanément, sans animation.
  • smooth — anime le défilement à l’aide d’une fonction d’accélération et d’une durée définies par le navigateur.

Une précision importante : scroll-behavior n’affecte pas le défilement déclenché par la molette de la souris, le pavé tactile ou le glissement de la barre de défilement par l’utilisateur. Elle s’applique uniquement au défilement déclenché par ancres et de manière programmatique.

L’accélération et la durée sont entièrement contrôlées par le navigateur. Vous ne pouvez pas les personnaliser avec CSS seul. Si vous avez besoin d’une durée spécifique ou d’une courbe d’accélération personnalisée, vous devrez recourir à une solution JavaScript.

Ajouter le défilement fluide CSS à votre page

Appliquez scroll-behavior: smooth à l’élément html pour activer la navigation par défilement fluide sur l’ensemble de la page :

html {
  scroll-behavior: smooth;
}

Utilisez html, et non body. Lorsqu’elle est définie sur l’élément racine, la propriété s’applique à la fenêtre d’affichage. La définir sur body ne se propage pas à la fenêtre d’affichage — une source courante de confusion lorsque le défilement fluide ne fonctionne pas.

Cette unique déclaration gère automatiquement tout le défilement des liens d’ancrage. Pas de JavaScript, pas de dépendances.

Cas d’usage pratiques

Navigation par table des matières :

<nav>
  <a href="#intro">Introduction</a>
  <a href="#usage">Usage</a>
  <a href="#examples">Examples</a>
</nav>

Bouton de retour en haut :

<a href="#top">↑ Back to top</a>

Pour que le lien de retour en haut arrive tout en haut, assurez-vous qu’un élément avec id="top" existe en début de page, ou utilisez href="#" comme solution de repli. Les deux modèles fonctionnent immédiatement une fois que scroll-behavior: smooth est défini sur html.

Gérer les en-têtes fixes avec scroll-margin-top

Si votre mise en page comprend un en-tête fixe, les cibles d’ancrage défileront partiellement derrière celui-ci. Corrigez cela avec scroll-margin-top :

:target {
  scroll-margin-top: 80px; /* match your header height */
}

Pour une couverture plus large — incluant le défilement programmatique vers des éléments qui ne sont pas la cible :target actuelle — appliquez la règle directement aux éléments de section eux-mêmes :

section[id] {
  scroll-margin-top: 80px;
}

Cela décale l’endroit où le navigateur s’arrête lors de la navigation vers un élément ciblé — sans JavaScript.

Accessibilité : respecter prefers-reduced-motion

Certains utilisateurs souffrent de cinétose ou d’inconfort vestibulaire déclenché par le défilement animé. Respectez toujours la media query prefers-reduced-motion :

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

Ce modèle active le défilement fluide uniquement pour les utilisateurs qui n’ont pas désactivé les animations dans les paramètres de leur système d’exploitation. C’est l’approche recommandée pour une expérience de défilement accessible.

Compatibilité des navigateurs

scroll-behavior bénéficie d’une prise en charge universelle dans tous les navigateurs modernes — Chrome 61+, Firefox 36+, Edge 79+, Safari 15.4+ et Opera 48+. La prise en charge mondiale avoisine 95 %, donc aucun polyfill n’est nécessaire pour les projets actuels.

CSS ou JavaScript : que choisir ?

BesoinMeilleure approche
Défilement simple par liens d’ancrageCSS
Durée ou accélération personnaliséeJavaScript
Défilement conditionnel ou piloté par logiqueJavaScript

Pour la plupart des scénarios de navigation interne — sites de documentation, pages d’atterrissage, portfolios — CSS est suffisant et préférable. Moins de code, pas de dépendances, performances natives du navigateur.

Checklist d’implémentation rapide

  • ☐ Appliquer scroll-behavior: smooth à html, et non à body
  • ☐ L’encadrer dans prefers-reduced-motion: no-preference
  • ☐ Ajouter scroll-margin-top pour les mises en page avec en-tête fixe
  • ☐ Tester les liens d’ancrage et la navigation au clavier
  • ☐ Vérifier le comportement sur iOS Safari

Conclusion

Le défilement fluide CSS fait partie de ces améliorations qui ne coûtent presque rien à implémenter et qui rendent immédiatement la navigation interne plus intentionnelle. Une seule déclaration, correctement placée, couvre la majorité des cas d’usage réels sans toucher à JavaScript.

FAQ

La propriété scroll-behavior doit être définie sur le conteneur défilant qui possède la fenêtre d'affichage, c'est-à-dire l'élément html. Lorsqu'elle est appliquée à body, la valeur ne se propage pas au défileur au niveau de la fenêtre d'affichage, et le défilement des liens d'ancrage revient au saut instantané par défaut. Déplacez la règle vers html et l'animation fluide fonctionnera comme prévu.

Non. La durée d'animation et la courbe d'accélération sont entièrement déterminées par le navigateur et ne peuvent pas être personnalisées via CSS. Si votre design nécessite une vitesse spécifique ou une fonction d'accélération personnalisée, vous avez besoin d'une solution JavaScript utilisant window.scrollTo avec behavior smooth combinée à une logique d'animation personnalisée, ou d'une petite bibliothèque qui gère le timing manuellement.

Non. La propriété s'applique uniquement au défilement programmatique et déclenché par ancres, comme cliquer sur un lien hash, appeler scrollIntoView, ou invoquer window.scrollTo. Le défilement initié par l'utilisateur via la molette de la souris, les gestes du pavé tactile, le glissement de la barre de défilement ou les touches fléchées du clavier reste inchangé et continue d'utiliser le comportement de défilement natif du navigateur.

Utilisez la propriété scroll-margin-top sur l'élément cible avec une valeur égale à la hauteur de votre en-tête. Par exemple, définir scroll-margin-top à 80px sur les éléments section avec un id décale la position d'atterrissage du défilement de sorte que la section apparaisse sous l'en-tête fixe au lieu d'être masquée derrière lui. Aucun JavaScript ni balisage supplémentaire n'est requis.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay