Skip to main content

CSS Effects

Scroll Snap

Written by Published

Create deliberate scroll destinations, offsets, and snapping without trapping users. You will build anchor offsets, smooth scrolling, horizontal snap galleries, proximity and mandatory snapping, and a reduced-motion fallback.

Scroll behavior controls how a scroll position is reached. Scroll snap defines preferred resting positions inside a scroll container after the user scrolls.

These features should assist navigation rather than take control away from it. Scroll padding and margin solve practical problems such as sticky headers covering an anchor. Proximity snapping can make a gallery easier to browse, while mandatory snapping can make oversized or zoomed content impossible to reach. This topic also connects with CSS Overflow and Preference Media Queries.

Account for sticky interface chrome

Example

css

html {
  scroll-behavior: smooth;
  scroll-padding-block-start: 5rem;
}

section {
  scroll-margin-block-start: 5rem;
}

scroll-padding belongs to the scroll container; scroll-margin belongs to the target. Both help prevent anchored content from landing behind a sticky header.

Snap a horizontal gallery

Example

css

.gallery {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(85%, 24rem);
  overflow-x: auto;
  scroll-snap-type: inline proximity;
}

.gallery > * {
  scroll-snap-align: start;
}

Use proximity for gentle assistance. Mandatory snapping can make tall items or zoomed content difficult to reach.

Example

css

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

Scroll boundaries and scrollbars

overscroll-behavior controls scroll chaining at a container boundary. Standard scrollbar properties can adjust width and color, but contrast and platform conventions must remain usable.

Example

css

.panel {
  overflow: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: #64748b #e2e8f0;
}

Understand scroll anchoring

Browsers normally adjust the scroll position when content above the viewport changes size. If that correction is harmful in a specific dynamic region, overflow-anchor: none opts that region out of anchor selection. Use it narrowly because disabling scroll anchoring can reintroduce unexpected page jumps.

Example

css

.live-scoreboard {
  overflow-anchor: none;
}

Scrolling Properties

PropertyPurposeExample
scroll-behaviorControls programmatic and anchor scrolling.scroll-behavior: smooth
scroll-snap-typeSets the snap axis and strictness.scroll-snap-type: x mandatory
scroll-snap-alignSets an item's snap position.scroll-snap-align: start
scroll-marginAdds space around a snap or anchor target.scroll-margin-block: 5rem
overflow-anchorOpts a region out of scroll-anchor selection.overflow-anchor: none

Complete Example

Run the complete document below in the Try It editor. Resize the preview or interact with the controls where the example calls for it.

Complete runnable example

html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Scroll Snap example</title>
  <style>
    * { box-sizing: border-box; }
    body {
      margin: 0;
      padding: 2rem;
      font-family: system-ui, sans-serif;
      line-height: 1.5;
    }
    main { max-width: 70rem; margin-inline: auto; }
    article, section, aside, form, .card, .panel {
      padding: 1rem;
      border: 1px solid #cbd5e1;
      border-radius: 0.6rem;
    }

html {
  scroll-behavior: smooth;
  scroll-padding-block-start: 5rem;
}

section {
  scroll-margin-block-start: 5rem;
}

.gallery {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(85%, 24rem);
  overflow-x: auto;
  scroll-snap-type: inline proximity;
}

.gallery > * {
  scroll-snap-align: start;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

.panel {
  overflow: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: #64748b #e2e8f0;
}

.live-scoreboard {
  overflow-anchor: none;
}
  </style>
</head>
<body>
  <main><nav><a href="#target">Jump to target</a></nav><section class="gallery"><article>Slide one</article><article>Slide two</article><article>Slide three</article></section><section id="target"><h2>Anchor target</h2></section></main>
</body>
</html>

Browser Support

Feature
Chrome
Edge
Firefox
Safari
scroll-snap-type69799911
scroll-behavior: smooth61793615.4
overflow-anchor56796627

Versions show the first stable desktop release with unprefixed support. Data source: MDN Browser Compatibility Data 8.0.8. A partial-support note is included where it changes how the example behaves.

Notes

  • Test the example with real content, keyboard input, browser zoom, and the narrowest layout your project supports.
  • Use a fallback when the support table shows that one of your required browsers predates the feature.

Conclusion

Scroll assistance should clarify navigation without trapping users or overriding reduced-motion preferences.

Prefer native scrolling with light guidance, preserve every intermediate position a reader may need, and disable smooth movement when reduced motion is requested. Test with touch, keyboard, trackpad, scroll wheel, zoom, and content taller than the snap container.