CSSScroll Snap

Scroll Snap

CSS Scroll Snap lets a scrollable container automatically stop — "snap" — at specific points as the user scrolls, instead of coming to rest wherever momentum happens to run out. This is the mechanism behind image carousels, full-page sections, and swipeable card decks that always land cleanly on an item, and it does all of it with two properties: no JavaScript, no scroll-event listeners, no manual position calculations.

scroll-snap-type: setting up the container
scroll-snap-type goes on the scrollable container and takes an axis (x, y, or both) plus a strictness (mandatory always snaps, while proximity only snaps if the container comes to rest near a snap point):

CSS
.carousel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
scroll-snap-align: marking the snap points
scroll-snap-align goes on the children — it marks which edge of each child should align with the container when it snaps (start, center, or end):

CSS
.carousel__item {
  flex: 0 0 100%;
  scroll-snap-align: center;
}
Worked example: an image carousel

Combining the two properties on a horizontally scrolling flex container produces a gallery where each image snaps fully into view:

CSS
.gallery {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: 1rem; /* keeps items clear of the container edge */
}

.gallery__image {
  flex: 0 0 80%;
  scroll-snap-align: center;
  border-radius: 8px;
}

HTML
<div class="gallery">
  <img class="gallery__image" src="photo-1.jpg" alt="" />
  <img class="gallery__image" src="photo-2.jpg" alt="" />
  <img class="gallery__image" src="photo-3.jpg" alt="" />
</div>

The user can scroll or swipe through this container with a mouse wheel, trackpad, or touchscreen, and it always comes to rest with one image centered — no carousel library required.

scroll-snap-stop: preventing skipped snap points
On a fast swipe or scroll, the browser may fling past several snap points and only stop at the one closest to where momentum runs out — skipping items in between. scroll-snap-stop: always forces the browser to stop at every snap point it passes, one at a time, regardless of scroll speed:

CSS
.gallery__image {
  scroll-snap-align: center;
  scroll-snap-stop: always; /* can't be flung past — one item per gesture */
}

Property

Applied to

Purpose

scroll-snap-type

Scroll container

Enables snapping and its axis/strictness

scroll-snap-align

Snap targets (children)

Marks which edge aligns on snap

scroll-snap-stop

Snap targets (children)

Forces stopping at every point, no skipping

mandatory can trap users with very few items or very wide items
scroll-snap-type: x mandatory forces the browser to always rest on a snap point, which can feel awkward if items are wider than the container or if there's empty trailing space with no snap point to land on. When in doubt, proximity is a gentler default that only snaps when the user scrolls near a snap point in the first place.
Scroll snap is purely a CSS layer on top of normal scrolling
The container still scrolls exactly as it would without snap points — with the mouse wheel, trackpad, touch, or keyboard. Snap points only adjust where the scroll comes to rest, so all of the browser's native scrolling accessibility (keyboard scrolling, scrollbar dragging) keeps working.
Next
Keep a scroll container's own scrolling from spilling over into the page behind it: overscroll-behavior.