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.
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
/* 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.
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
/* 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 :
Valeurs sur deux axes
Vous pouvez aussi specifier des alignements differents pour chaque axe :
/* 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.
/* 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 :
<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.
.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);
}
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 !
/* 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 :
/* 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 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 :
/* 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 :
.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 :
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 :
/* 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 */
}
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
/* 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-typesur le conteneur pour activer le snapscroll-snap-alignsur les enfants pour definir les points d'alignementmandatorypour un controle strict,proximitypour plus de libertescroll-paddingpour 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 !
Decouvrez nos templates avec Scroll Snap pre-integre dans notre bibliotheque d'effets, prets a etre utilises dans vos projets.