- Home
- /
- Tutorials
- /
- CSS Tutorial
- /
- Scroll Snap
CSS Effects
Scroll Snap
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
| Property | Purpose | Example |
|---|---|---|
| scroll-behavior | Controls programmatic and anchor scrolling. | scroll-behavior: smooth |
| scroll-snap-type | Sets the snap axis and strictness. | scroll-snap-type: x mandatory |
| scroll-snap-align | Sets an item's snap position. | scroll-snap-align: start |
| scroll-margin | Adds space around a snap or anchor target. | scroll-margin-block: 5rem |
| overflow-anchor | Opts 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-type | 69 | 79 | 99 | 11 |
| scroll-behavior: smooth | 61 | 79 | 36 | 15.4 |
| overflow-anchor | 56 | 79 | 66 | 27 |
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.
