Overview
CSS Scroll Snap turns a horizontally-scrolling track into a carousel-style snap rail with three lines of CSS: set scroll-snap-type on the container, scroll-snap-align on each child, and scroll-padding when there is a sticky header in the way. The pattern is solved in CSS terms; the production caveats are what break it — a tall outlier card that does not match the snap stride, a focus ring clipped behind the snap target, a sticky control that hides the next snap point.
When to use it
Reach for scroll-snap when you have a sequence of equal-importance items that the user wants to land on individually — image galleries, product carousels, onboarding pagers, week views in a calendar. Skip it for vertical reading content; snap interrupts the natural scroll rhythm and pages where the user is reading rather than skimming feel hostile. Skip it on long lists where snapping every card kills momentum scroll — reach forproximity instead of mandatory there.
How it works
scroll-snap-type: x mandatory tells the browser that every scroll position rounds to the nearest snap point on the x-axis. scroll-snap-align: center on each card declares that card’s center as a snap target. The browser does the interpolation — flick the rail with a finger and it decelerates onto the nearest snap. Use proximity instead of mandatory when you want the user to be able to land between snap points; the browser only snaps when the velocity is low enough. scroll-padding on the container reserves space for sticky chrome (sidebars, headers) so the snap target lands inside the visible viewport.
Production gotchas
The Padding Trap: if you have a sticky header above the rail and no scroll-padding-top matching its height, the snap target slides under the header and the user sees a card with its top edge hidden. Always pair sticky elements with matching scroll-padding. Tall outlier cards (a featured item that breaks the equal-stride assumption) confuse the browser’s snap prediction — if the next snap point is past the outlier’s height, momentum scroll can overshoot the snap entirely. Keyboard focus does not automatically scroll the focused card into the snap zone; you need to wire scrollIntoView() or use the newer focus-visible + scroll-snap-stoppairing for keyboard parity with mouse-flick parity.
Accessibility
Snap mandatory mode interferes with screen-reader virtual-cursor scrolling on some assistive-tech configurations — AT users cannot freely move through the document because the browser keeps snapping back. Provide proximity mode as a fallback when reduced-motion is set, and ensure keyboard users can step through cards one snap point at a time without hitting a focus trap inside an off-screen card.
References
Implementation depth
Scroll snap is best when every item is meant to be consumed as a discrete stop. Pair scroll-snap-type with scroll-padding so sticky headers and side controls do not hide the item the browser just snapped into view.
Keyboard focus is the usual gap. A card can be visually snapped while focus lands inside an off-screen child, so test Tab and Shift+Tab, not just touch flicks. For long reading flows, proximity is usually safer than mandatory.