Nommé à l'origine Scroll Snap Points, puis CSS Scroll Snap, ce module, qui est candidat au statut de recommandation , introduit les positions d'accroche lors du défilement garantissant ainsi la position sur laquelle on arrive après avoir fait défiler du contenu.
Si cette définition est un peu floue pour l'instant, rassurez-vous, les exemples plus bas vous aideront à comprendre le principe et surtout l'intérêt d'un tel module en CSS.
Le module CSS Scroll Snap fonctionne sur Safari iOS à condition que le conteneur possède la propriété -webkit-overflow-scrolling avec la valeur touch et que le contenu soit enveloppé par la propriété overflow ayant pour valeur visible.
Propriété scroll-snap-type :
Comme dans chaque module CSS, on y retrouve de nouvelles propriétés. La propriété la plus importante qui s'applique à l'élément conteneur est scroll-snap-type.
Cette propriété va permettre de définir la force d'adhérence aux points d'accroche lors du défilement de l'élément conteneur. C'est l'agent utilisateur, autrement dit le navigateur, qui va se charger de la gestion de ces points d'accroche. Bien entendu, nous aurons besoin que notre conteneur possède la propriété overflow afin de rendre celui-ci défilant.
Les valeurs pour cette propriété sont les suivantes :
none : valeur initiale.
x : axe horizontal.
y : axe vertical.
block : axe de bloc.
inline : axe en ligne.
both : axe horizontal et vertical.
De plus il existe deux mots-clé qui peuvent s'associer aux valeurs ci-dessus (dont nous parlerons un peu plus bas) :
.exemple-scroll-both {
display:grid;/*1 - pour un alignement horizontal et vertical*/
grid:repeat(3, 20vw)/ repeat(5, 20vw);
gap:1rem;
max-width:60vmin;
aspect-ratio:1;
overflow: auto;/*2*/
scroll-snap-type:both;/*3*/
}
.exemple-scroll-both div {
display: flex;
justify-content: center;
align-items: center;
}
Ce module nécessite un modèle d'alignement de boîte, d'où l'utilisation de la valeur flex (on peut aussi utiliser la valeur grid comme sur l'exemple avec la valeur both de la propriété scroll-snap-type) dans le conteneur. La mise en place n'en est que plus simple.
La propriété scroll-snap-type ne fait que poser les bases qui permettra le contôle du défilement.
C'est là que la propriété scroll-snap-align fait son apparition.
Propriété scroll-snap-align :
La propriété scroll-snap-align définit la position de la boîte d'accroche (que l'on nomme snap positions). Elle comprend deux valeurs qui s'appliquent respectivement à l'axe x et à l'axe y. Lorsqu'une seule valeur est fournie, la seconde prendra par défaut la valeur de la première.
Il existe quatre valeurs à cette propriété :
none : valeur initiale. Aucune position d'accroche.
start : l'élément sera aligné au début du conteneur, à gauche sur l'axe x, en haut sur l'axe y.
center : l'élément sera aligné au centre du conteneur, que ce soit sur l'axe x ou y.
end : l'élément sera aligné à droite du conteneur sur l'axe x et tout en bas sur l'axe y.
La propriété scroll-snap-align doit toujours se trouver dans l'élément enfant du conteneur et non pas dans le conteneur lui-même. Nous allons utiliser un exemple pour chaque valeur afin que vous puissiez distinguer la différence (le fonctionnement est le même que ce soit sur l'axe x ou y):
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
Parfait. Nous avons passé en revue les deux principales propriétés du module. Mais, comme vous avez pu le remarquer, lorsqu'on clique sur la barre du scroll, les points d'accroche sont plus ou moins bien respectés.
Souvenez-vous, nous avons évoqué en début d'article la propriété scroll-snap-type et ses valeurs mandatory et proximity qui spécifient la rigueur de la sélection du défilement (ou zone de capture).
Exemple avec la valeur proximity (avec alignement au centre) :
1
2
3
4
5
Exemple avec la valeur mandatory (avec alignement au centre) :
1
2
3
4
5
Nous pouvons constater que seule la valeur mandatory permet un contrôle optimal de la zone de capture. En effet, avec le valeur proximity, c'est le navigateur qui décide si l'élément va s'aligner à un point d'accrochage donné.
Les autres propriétés :
On notera quelques propriétés raccourcies supplémentaires, à savoir :
scroll-padding : applicable au conteneur visant à réduire la zone de défilement considérée comme visible. Elle comprend les propriétés suivantes et agit comme la propriété padding :
- scroll-padding-top
- scroll-padding-right
- scroll-padding-bottom
- scroll-padding-left
1
2
3
4
5
scroll-margin : applicable aux éléments enfants. Valeur initiale à zéro. Comprend les propriétés suivantes et agit comme la propriété margin :
- scroll-margin-top
- scroll-margin-left
- scroll-margin-bottom
- scroll-margin-right
Dans l'exemple ci-dessous, nous avons appliqué une marge de 2rem. Vous allez donc constater en descendant la barre de défilement que chaque élément, hormis le premier, va se présenter en haut avec une marge.
1
2
3
4
5
scroll-snap-stop : définit la façon dont le conteneur peut ne pas prendre en compte certaines positions d'accroche. Cette propriété comprend deux valeurs :
- normal : valeur initiale. Permet de passer sur certaines positions d'accroche.
- always : force le conteneur à s'accrocher à la première position d'accroche d'un élément.
Cette propriété peut s'avérer utile notamment sur les appareils mobiles où l'utilisateur peut faire défiler le contenu très rapidement d'un seul coup, le navigateur ignorant ainsi plusieurs points de capture potentiels.
La propriété scroll-snap-stop permet alors de forcer le défilement à s’arrêter sur un ou plusieurs éléments en particulier.
Dans l'exemple ci-dessous, nous avons utilisé la valeur always et nous avons défini l'alignement à gauche (start)
1
2
3
4
5
Par ailleurs, il existe le deuxième niveau que vous pouvez découvrir dans la spécification . Vous pouvez également vous rendre sur cette page pour voir quelques démonstrations avec les nouvelles propriétés de ce second niveau.
Les possibilités :
Slider
Un exemple classique de slider avec le module CSS Scroll Snap. On notera l'utilisation de la propriété scroll-behavior pour une transition plus douce dans le défilement des images. Vous pouvez suivre pas à pas la mise en place de ce slider dans la démonstration ci-dessous :