CSS scroll snapping
Carousels and galleries that lock into place β no JavaScript.
Scroll snapping lets the browser settle a scroll container on tidy resting points. Declare the snap behaviour on the scroller, the alignment on each child, and panning glides to crisp stops instead of drifting mid-item.
Two properties, two jobs
Scroll snapping is a partnership. scroll-snap-type goes on the scroll container and turns snapping on, naming the axis (x, y, or both) and the strictness (mandatory or proximity). scroll-snap-align goes on each child and marks where that child should come to rest relative to the scrollport β start, center, or end.
Without an align value on the children, a snap-type on the parent does nothing: the container knows it should snap, but no element has volunteered a snap point.
Mandatory vs proximity
mandatory forces the scroller to always finish on a snap point β great for full-screen sections or a one-item-at-a-time carousel where partial views make no sense. proximity only snaps when you let go near a snap point, leaving free scrolling otherwise β kinder for long lists where forcing a stop on every item would feel sticky.
Padding, margin, and comfort
scroll-padding on the container insets the snap area, so a snapped item clears a sticky header instead of hiding under it. scroll-margin on a child adds breathing room around its own snap point. Pair snapping with scroll-behavior: smooth so programmatic jumps (anchor links, scrollIntoView) animate to the snap point too.
Try it 4 examples
Horizontal snap carousel
HTML+CSS+JSintroscroll-snap-type: x mandatory on the flex row plus scroll-snap-align: start on each .slide means a horizontal flick always settles with one card's left edge at the scrollport start, never mid-card. scroll-padding: 16px insets that rest position so the snapped card clears the container's own padding instead of butting against the dashed border.