Ce qui est inclus
Un conteneur de sections qui s’aimantent au défilement : chaque panneau remplit exactement le cadre et s’arrête sur son propre bord, avec une barre à droite qui dit où l’on en est. Deux fichiers, une feuille de style et un script. Aucune dépendance, aucune étape de build, aucune requête externe.
L’aimantation elle-même est du CSS natif
(scroll-snap-type) : la molette, le pavé tactile,
le doigt et la barre de défilement du navigateur continuent de
faire ce qu’ils font partout ailleurs. Le script ne dessine que
la barre et rend le clavier utilisable.
Fonctionnalités
- Marche sans JavaScript — l’aimantation, le plein cadre et le défilement sont natifs. Tant que le script n’a pas tourné, la barre du navigateur reste en place : un indicateur figé qui mentirait sur la position serait pire que pas d’indicateur du tout.
-
Clavier complet — flèches, Page précédente,
Page suivante, Début, Fin et la barre d’espace passent d’un
panneau au suivant. Ce n’est pas un confort : sous
mandatory, une flèche fait quarante pixels que l’aimant ramène aussitôt, donc sans cela le composant ne se pilote pas du tout au clavier. - Une ligne d’état pour les lecteurs d’écran — « Panneau 2 sur 4 » à chaque changement. Le libellé est un attribut, pas une chaîne dans le script : il se traduit sans toucher au code.
-
Une variable pour l’échelle — largeur de la
barre, arrondi et corps du texte dérivent tous de
--ss-font-size. La barre grossit avec le reste au lieu de rester un trait de 6 px. -
Autant de panneaux qu’on veut — la hauteur
du curseur est
100 % / N, comptée par le script. Ajoutez ou retirez un panneau après coup, il se recompte. -
Mouvement réduit, couleurs forcées — sous
prefers-reduced-motion, le fondu d’entrée et les sauts fluides tombent à zéro ; sousforced-colors, la barre reprend les couleurs du système.
Le poser dans une page
Deux fichiers à charger, puis le balisage :
<link rel="stylesheet" href="snap-sections.css">
<script src="snap-sections.js" defer></script>
<div class="snap-sections" data-ss-status="Panneau %n sur %total">
<div class="snap-sections__viewport" tabindex="0"
role="group" aria-label="Panneaux aimantés">
<section class="snap-sections__panel">Premier</section>
<section class="snap-sections__panel">Deuxième</section>
<section class="snap-sections__panel">Troisième</section>
</div>
<div class="snap-sections__rail" aria-hidden="true">
<div class="snap-sections__thumb"></div>
</div>
<p class="snap-sections__status" role="status"></p>
</div>
Une seule chose à ne pas oublier : le composant fait 100 % de
la hauteur de son parent et n’en invente pas. C’est donc la
page qui dit la hauteur de la scène —
height: 100svh pour du plein écran, une hauteur
fixe pour un encart au milieu d’un article.
Ce qu’il faut savoir
- La barre passe par-dessus le contenu. Elle est posée à droite, collée au bord, sans colonne à elle — comme sur la référence. Les six derniers pixels d’un panneau passent donc dessous. Si son contenu doit la dégager, on lui donne une marge intérieure à droite.
- Un cran de molette isolé ne change pas de panneau. L’aimantation est stricte : un défilement plus court que la moitié d’un panneau est ramené à son point de départ. Un geste continu passe sans rien remarquer — le navigateur additionne les crans —, mais une souris à crans francs demande un coup net. C’est le comportement du CSS natif, pas celui de ce composant ; le clavier, lui, avance toujours d’un panneau entier.
-
Au bout du dernier panneau, la page reprend.
Le défilement n’est ni capturé ni détourné : c’est le
comportement du navigateur, et celui de la référence. Un
overscroll-behavior: containl’enfermerait, mais ce n’est pas ce que fait l’original. -
Un défaut de la référence a été corrigé. Sur
l’original, le curseur ne parcourt que sa propre hauteur :
avec quatre panneaux, il s’arrête au quart de la barre alors
qu’on est arrivé en bas. Ici il parcourt la course entière.
Le comportement d’origine reste accessible par une variable,
--ss-thumb-travel: 100%, et le README explique d’où vient l’erreur. -
Aucun style ni script en ligne. Le composant
respecte la politique de sécurité stricte du site et
n’utilise jamais
innerHTML: la position du curseur passe par une propriété personnalisée, que le CSSOM accepte là où une balise<style>serait refusée. - Le dessin vient d’ailleurs. Les proportions et le comportement reprennent ceux d’un composant Framer publié, relevés sur le site en ligne — les boîtes tombent au centième de pixel. Le code, lui, est original : c’est du CSS et du JavaScript ordinaires là où l’original s’appuie sur React et une bibliothèque d’animation.
Prends-le, ouvre-le, casse-le.
Ce composant est gratuit. La bibliothèque complète — les templates et les autres composants — est incluse dans l’abonnement, avec la formation.
Accès immédiat · Sans engagement · Annulation en 1 clic