Blog / CSS

CSS Scroll Snap : le guide complet pour des navigations fluides

Maitrisez CSS Scroll Snap pour creer des experiences de scroll magnetique : sections plein ecran, carrousels natifs et galeries fluides. Sans JavaScript, compatible tous navigateurs.

Introduction au Scroll Snap

Vous avez certainement deja visite ces sites web ou le scroll semble "magnetique" - la page s'arrete automatiquement sur chaque section de maniere fluide et precise. Avant CSS Scroll Snap, ce type d'experience necessitait des librairies JavaScript complexes comme fullPage.js ou des calculs manuels de position.

Aujourd'hui, grace a CSS Scroll Snap, vous pouvez creer ces experiences nativement, avec quelques lignes de CSS seulement. Le resultat ? Des performances optimales, une compatibilite navigateur excellente, et zero dependance JavaScript.

💡
Bon a savoir

CSS Scroll Snap est supporte par tous les navigateurs modernes depuis 2019 (Chrome, Firefox, Safari, Edge). Plus de 96% des utilisateurs peuvent en profiter sans aucun polyfill.

Dans ce guide complet, nous allons explorer toutes les proprietes de Scroll Snap, comprendre leurs differences, et construire des demos pratiques que vous pourrez directement reutiliser dans vos projets.

La propriete scroll-snap-type

La propriete scroll-snap-type est le point de depart de toute implementation. Elle se definit sur le conteneur scrollable (l'element parent) et accepte deux parametres : l'axe et le comportement.

Syntaxe de base

scroll-snap-type.css
/* Syntaxe : scroll-snap-type: [axe] [comportement]; */

/* Scroll horizontal obligatoire */
.container {
  scroll-snap-type: x mandatory;
}

/* Scroll vertical optionnel */
.container {
  scroll-snap-type: y proximity;
}

/* Les deux axes en meme temps */
.container {
  scroll-snap-type: both mandatory;
}

Les valeurs d'axe

Valeur Description Cas d'usage
x Snap horizontal uniquement Carrousels, galeries horizontales
y Snap vertical uniquement Sections plein ecran, landing pages
both Snap sur les deux axes Grilles d'images, tableaux interactifs
none Desactive le snap Desactivation conditionnelle

Mandatory vs Proximity

C'est ici que la magie opère. La difference entre mandatory et proximity est cruciale pour l'experience utilisateur.

  • mandatory : Le scroll s'arrete TOUJOURS sur un point de snap. Meme un petit scroll forcera l'alignement. Ideal pour des sections plein ecran ou l'utilisateur doit voir chaque section completement.
  • proximity : Le snap ne s'active que si l'utilisateur est proche d'un point de snap. Permet un scroll plus libre tout en offrant un alignement contextuel.
mandatory
1
2
3
4
proximity
1
2
3
4
Faites defiler pour comparer les comportements
⚠️
Attention avec mandatory

Utilisez mandatory avec precaution sur des conteneurs avec du contenu variable. Si un element est plus grand que le viewport, l'utilisateur pourrait se retrouver bloque sans pouvoir voir tout le contenu.

La propriete scroll-snap-align

Une fois le conteneur configure, chaque element enfant peut definir son point d'alignement avec scroll-snap-align. Cette propriete se place sur les elements enfants.

Les trois valeurs principales

scroll-snap-align.css
/* L'element s'aligne au debut du conteneur */
.item {
  scroll-snap-align: start;
}

/* L'element s'aligne au centre du conteneur */
.item {
  scroll-snap-align: center;
}

/* L'element s'aligne a la fin du conteneur */
.item {
  scroll-snap-align: end;
}

/* Pas de snap pour cet element */
.item {
  scroll-snap-align: none;
}

Voici une demonstration interactive montrant la difference entre les trois alignements :

start
center
end
start
center
Observez comment chaque element s'aligne differemment

Valeurs sur deux axes

Vous pouvez aussi specifier des alignements differents pour chaque axe :

snap-align-dual.css
/* Syntaxe : scroll-snap-align: [block] [inline]; */

/* Centre vertical, debut horizontal */
.item {
  scroll-snap-align: center start;
}

/* Debut vertical, centre horizontal */
.item {
  scroll-snap-align: start center;
}

Creer des sections plein ecran

L'un des cas d'usage les plus populaires de Scroll Snap est la creation de sections plein ecran, comme on peut le voir sur de nombreuses landing pages modernes.

Section Hero Premiere impression impactante
Features Presentez vos avantages
Temoignages Preuve sociale
Call to Action Convertissez vos visiteurs
Scrollez verticalement dans la demo
fullpage-sections.css
/* Conteneur principal - prend tout le viewport */
.fullpage-container {
  height: 100vh;
  overflow-y: auto;
  scroll-snap-type: y mandatory;

  /* Masquer la scrollbar (optionnel) */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.fullpage-container::-webkit-scrollbar {
  display: none;
}

/* Chaque section prend 100% du viewport */
.section {
  height: 100vh;
  scroll-snap-align: start;

  /* Centrage du contenu */
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Couleurs differentes pour chaque section */
.section:nth-child(1) {
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
}

.section:nth-child(2) {
  background: linear-gradient(135deg, #8b5cf6, #d946ef);
}

.section:nth-child(3) {
  background: linear-gradient(135deg, #d946ef, #f43f5e);
}

Et le HTML correspondant :

fullpage-sections.html
<div class="fullpage-container">
  <section class="section">
    <h1>Bienvenue</h1>
    <p>Decouvrez notre produit</p>
  </section>

  <section class="section">
    <h2>Fonctionnalites</h2>
    <!-- Contenu -->
  </section>

  <section class="section">
    <h2>Tarifs</h2>
    <!-- Contenu -->
  </section>
</div>

Creer un carrousel horizontal

Les carrousels sont un autre cas d'usage parfait pour Scroll Snap. Voici comment creer un carrousel de cartes produits ou de temoignages, sans une seule ligne de JavaScript.

Faites defiler les cartes
carousel.css
.carousel {
  display: flex;
  gap: 20px;
  padding: 20px;

  /* Activation du scroll horizontal */
  overflow-x: auto;
  scroll-snap-type: x mandatory;

  /* Masquer la scrollbar */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.carousel::-webkit-scrollbar {
  display: none;
}

.carousel-card {
  /* Taille fixe pour chaque carte */
  flex: 0 0 280px;

  /* Point de snap au debut de chaque carte */
  scroll-snap-align: start;

  /* Styles visuels */
  background: #12121a;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 16px;
  padding: 24px;
  transition: transform 0.3s ease;
}

.carousel-card:hover {
  transform: translateY(-4px);
}
💡
Astuce : Padding pour le premier/dernier element

Ajoutez du padding au conteneur pour que le premier et le dernier element ne soient pas colles aux bords. Le snap fonctionnera toujours correctement.

scroll-padding et accessibilite

La propriete scroll-padding est souvent negligee mais elle est cruciale pour l'accessibilite et l'experience utilisateur, surtout quand vous avez une navigation fixe en haut de page.

Le probleme des headers fixes

Imaginez : vous avez un header fixe de 80px de hauteur et des sections plein ecran. Sans scroll-padding, le haut de chaque section sera cache derriere votre header !

scroll-padding.css
/* Le conteneur avec un header fixe de 80px */
.container {
  scroll-snap-type: y mandatory;

  /* Compense la hauteur du header */
  scroll-padding-top: 80px;
}

/* Variante avec padding sur tous les cotes */
.container {
  scroll-padding: 80px 20px 20px 20px;
}

/* Pour un carrousel horizontal avec padding lateral */
.carousel {
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 24px;
}

scroll-margin : l'alternative sur les enfants

Vous pouvez aussi utiliser scroll-margin sur les elements enfants pour un controle plus fin :

scroll-margin.css
/* Applique sur chaque element enfant */
.section {
  scroll-snap-align: start;

  /* Marge de scroll de 80px en haut */
  scroll-margin-top: 80px;
}

/* Utile pour des marges differentes par element */
.hero-section {
  scroll-margin-top: 0; /* Pas de marge pour le hero */
}

.content-section {
  scroll-margin-top: 80px; /* Marge pour le header */
}
📋
scroll-padding vs scroll-margin

scroll-padding se met sur le conteneur et affecte tous les enfants. scroll-margin se met sur les enfants individuellement pour un controle plus precis.

Accessibilite et prefers-reduced-motion

Certains utilisateurs sont sensibles aux mouvements brusques. Bien que Scroll Snap n'anime pas directement le scroll, le comportement "magnetique" peut etre desorientant. Voici comment respecter les preferences utilisateur :

accessibility.css
/* Configuration par defaut */
.container {
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
}

/* Desactiver pour les utilisateurs sensibles */
@media (prefers-reduced-motion: reduce) {
  .container {
    /* Passer en proximity pour un comportement moins agressif */
    scroll-snap-type: y proximity;
    scroll-behavior: auto;
  }
}

Exemples pratiques avances

Maintenant que vous maitrisez les bases, voyons quelques patterns plus avances que vous pouvez implementer.

Galerie d'images avec scroll snap

Une galerie qui permet de naviguer naturellement entre les images :

Naviguez dans la galerie
gallery-snap.css
.gallery {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  gap: 0;

  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;

  scrollbar-width: none;
}

.gallery-image {
  scroll-snap-align: start;
  width: 100%;
  height: 400px;
  object-fit: cover;
}

Scroll snap avec indicateurs

Ajoutez des indicateurs de pagination qui se mettent a jour automatiquement. Cela necessite un peu de JavaScript :

snap-indicators.js
const carousel = document.querySelector('.carousel');
const items = carousel.querySelectorAll('.carousel-item');
const dots = document.querySelectorAll('.dot');

// Detecter l'element visible apres le scroll
carousel.addEventListener('scroll', () => {
  const scrollLeft = carousel.scrollLeft;
  const itemWidth = items[0].offsetWidth;
  const currentIndex = Math.round(scrollLeft / itemWidth);

  // Mettre a jour les indicateurs
  dots.forEach((dot, index) => {
    dot.classList.toggle('active', index === currentIndex);
  });
});

// Clic sur un indicateur pour naviguer
dots.forEach((dot, index) => {
  dot.addEventListener('click', () => {
    items[index].scrollIntoView({
      behavior: 'smooth',
      inline: 'start'
    });
  });
});

Stop scroll avec scroll-snap-stop

La propriete scroll-snap-stop controle si l'utilisateur peut "sauter" par-dessus des elements lors d'un scroll rapide :

scroll-snap-stop.css
/* Par defaut : l'utilisateur peut sauter des elements */
.item {
  scroll-snap-stop: normal;
}

/* Force l'arret sur chaque element */
.item-important {
  scroll-snap-stop: always;
}

/* Cas d'usage : tutoriel etape par etape */
.tutorial-step {
  scroll-snap-align: start;
  scroll-snap-stop: always; /* Oblige a voir chaque etape */
}
⚠️
Support navigateur limite

scroll-snap-stop n'est pas supporte sur Firefox (seulement Chrome/Safari). Utilisez-le comme amelioration progressive.

Bonnes pratiques et erreurs a eviter

Avant de conclure, voici un resume des meilleures pratiques pour utiliser CSS Scroll Snap efficacement :

A faire

  • Testez sur mobile : Le comportement tactile peut differer du scroll a la souris
  • Utilisez scroll-padding pour les headers fixes
  • Preferez proximity pour du contenu de longueur variable
  • Ajoutez overscroll-behavior pour eviter les conflits avec le scroll parent
  • Respectez prefers-reduced-motion pour l'accessibilite

A eviter

  • mandatory sur du contenu variable : Peut bloquer l'utilisateur
  • Snap sur body/html directement : Problemes de compatibilite
  • Oublier le padding : Elements coupes par les bords
  • Trop de points de snap : Experience frustante
best-practices.css
/* Configuration recommandee */
.snap-container {
  scroll-snap-type: y mandatory;
  scroll-padding-top: 80px;
  overscroll-behavior: contain;
}

.snap-item {
  scroll-snap-align: start;
}

/* Accessibilite */
@media (prefers-reduced-motion: reduce) {
  .snap-container {
    scroll-snap-type: y proximity;
  }
}

/* Mobile-first */
@media (max-width: 768px) {
  .snap-container {
    scroll-padding-top: 60px; /* Header plus petit sur mobile */
  }
}

Conclusion

CSS Scroll Snap est un outil puissant qui vous permet de creer des experiences de navigation fluides et engageantes, sans dependre de librairies JavaScript lourdes. Que ce soit pour des sections plein ecran, des carrousels de produits ou des galeries d'images, les possibilites sont nombreuses.

Les points cles a retenir :

  • scroll-snap-type sur le conteneur pour activer le snap
  • scroll-snap-align sur les enfants pour definir les points d'alignement
  • mandatory pour un controle strict, proximity pour plus de liberte
  • scroll-padding pour compenser les elements fixes
  • Toujours penser a l'accessibilite avec prefers-reduced-motion

N'hesitez pas a experimenter avec les differentes proprietes pour trouver le comportement parfait pour votre projet. Le support navigateur est excellent, et vos utilisateurs apprecieront cette touche de polish supplementaire !

🎨
Allez plus loin

Decouvrez nos templates avec Scroll Snap pre-integre dans notre bibliotheque d'effets, prets a etre utilises dans vos projets.