PureDevTools

CSS Scroll Snap Generator

Configure scroll-snap-type, scroll-snap-align, scroll-padding, and scroll-margin. Live preview. Copy CSS instantly.

All processing happens in your browser. No data is sent to any server.

Container

scroll-snap-type — Axis

scroll-snap-type — Strictness

mandatory — always snaps to a snap point after scrolling

scroll-padding (container)


Snap Children

scroll-snap-align

scroll-snap-stop

normal (default) — fast flicks may skip multiple snap points

scroll-margin (children)

Live Preview

Scroll inside the box to see snap behavior. Each numbered slide is a snap target.

1
2
3
4
5

Current: scroll-snap-type: x mandatory  ·  scroll-snap-align: start

Generated CSS

.scroll-container {
  scroll-snap-type: x mandatory;
  overflow-x: scroll;
  overflow-y: hidden;
  display: flex;
  scroll-behavior: smooth;
}

.scroll-item {
  scroll-snap-align: start;
  flex: 0 0 100%;
}

You built a horizontal card carousel with overflow-x: auto and display: flex. It scrolls, but it stops at random positions — half a card visible on the left, a quarter of another on the right. You need it to “snap” so one card is always perfectly aligned. JavaScript scroll libraries (Swiper, Flickity) do this but add 30–80KB and need event listener management. CSS Scroll Snap does it in four CSS properties with zero JavaScript.

Why This Generator (Not Writing scroll-snap by Hand)

scroll-snap-type, scroll-snap-align, scroll-padding, and scroll-margin interact in ways that are hard to visualize from the spec alone. This tool gives you a live scrollable preview: pick axis and strictness, set alignment, adjust padding for fixed headers, and see the snapping behavior in real time. Copy the production-ready CSS when it looks right. Everything runs in your browser; no data is sent anywhere.

What Is CSS Scroll Snap?

CSS Scroll Snap is a set of CSS properties that control how a scroll container “snaps” to specific positions after the user finishes scrolling. Instead of leaving scroll position at an arbitrary offset, the browser moves the viewport to the nearest snap point — giving sliders, carousels, and full-page layouts a polished, intentional feel.

Scroll snap is entirely CSS-based, requires zero JavaScript, and is supported in all modern browsers including Safari 11+, Chrome 69+, and Firefox 68+.

The four properties this generator covers:

PropertyApplies toPurpose
scroll-snap-typeScroll containerSets axis and snap strictness
scroll-snap-alignSnap childrenSets which edge of the child snaps
scroll-paddingScroll containerOffsets the snap area inward (e.g., to avoid header overlap)
scroll-marginSnap childrenExpands or contracts each child’s snap area

scroll-snap-type: Axis and Strictness

scroll-snap-type goes on the scroll container — the element that has overflow: auto or overflow: scroll. It takes two values: axis and strictness.

Axis

scroll-snap-type: x mandatory;   /* Horizontal carousel */
scroll-snap-type: y mandatory;   /* Vertical full-page scroll */
scroll-snap-type: both mandatory; /* 2-D grid snap */

Strictness

scroll-snap-type: x mandatory;  /* Always snaps to nearest point */
scroll-snap-type: x proximity;  /* Snaps only when close to a snap point */

Use mandatory for discrete, one-at-a-time navigation (carousels, full-screen sections). Use proximity for feeds or long-scroll pages where you want occasional anchor points without forcing alignment every scroll.


scroll-snap-align: Aligning Child Items

scroll-snap-align goes on each snap child — the items inside the scroll container. It specifies which edge of the child should align to the snap area.

.snap-item { scroll-snap-align: start; }   /* Left/top edge snaps */
.snap-item { scroll-snap-align: center; }  /* Center snaps */
.snap-item { scroll-snap-align: end; }     /* Right/bottom edge snaps */

Choosing the right alignment:


scroll-padding: Creating a Safe Inset on the Container

scroll-padding shrinks the “snap port” — the area on the scroll container where snap alignment is calculated. Any fixed UI element overlapping the scroll area (like a sticky header, navigation bar, or sidebar) should be accounted for with scroll-padding.

.snap-container {
  scroll-snap-type: y mandatory;
  overflow-y: auto;
  scroll-padding: 80px 0 0 0; /* 80px top offset for a fixed header */
}

scroll-padding follows the same shorthand syntax as padding:

ShorthandMeaning
scroll-padding: 16pxAll four sides = 16px
scroll-padding: 16px 0Top/bottom = 16px, left/right = 0
scroll-padding: 16px 0 8pxTop = 16px, left/right = 0, bottom = 8px
scroll-padding: 16px 8px 4px 0Top, right, bottom, left

You can also use scroll-padding-top, scroll-padding-right, scroll-padding-bottom, and scroll-padding-left for individual sides.


scroll-margin: Adjusting Each Item’s Snap Offset

scroll-margin adds an outward offset to a snap child’s snap area, without affecting the element’s layout or visual appearance. Think of it as invisible extra space around the child that influences where the browser considers the “snap point” to be.

.snap-item {
  scroll-snap-align: start;
  scroll-margin-top: 16px; /* Snap 16px before the item's actual top edge */
}

Common use cases:

scroll-margin follows the same four-side shorthand rules as margin.


Common Patterns

.carousel {
  scroll-snap-type: x mandatory;
  overflow-x: auto;
  display: flex;
}

.carousel-slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

Each slide is exactly as wide as the visible area (flex: 0 0 100%), so one full slide is always visible.

Full-Page Vertical Scroll

.page-container {
  scroll-snap-type: y mandatory;
  overflow-y: auto;
  height: 100vh;
}

.page-section {
  height: 100vh;
  scroll-snap-align: start;
}

Classic full-page scroll where each section occupies the entire viewport height.

.carousel {
  scroll-snap-type: x mandatory;
  overflow-x: auto;
  display: flex;
  padding: 0 24px; /* Make room for peeking cards */
}

.carousel-slide {
  flex: 0 0 85%; /* Slightly less than 100% so adjacent cards peek */
  scroll-snap-align: center;
  scroll-margin: 0 8px; /* Small gap between cards */
}

Account for Fixed Header

.scroll-area {
  scroll-snap-type: y mandatory;
  overflow-y: auto;
  scroll-padding-top: 64px; /* Height of your fixed header */
}

.section {
  scroll-snap-align: start;
  scroll-margin-top: 64px; /* Mirrors the header height */
}

Browser Support and Fallback

CSS Scroll Snap is broadly supported with no vendor prefixes required:

BrowserSupport since
Chrome69 (2018)
Firefox68 (2019)
Safari11 (2017)
Edge79 (2020)
iOS Safari11 (2017)
Android Chrome69 (2018)

For older browsers, scroll behavior degrades gracefully — the scroll container still works but doesn’t snap. This means you can safely use scroll snap as a progressive enhancement with no fallback required.


Frequently Asked Questions

What is the difference between mandatory and proximity?

mandatory forces the scroll container to always land on a snap point after any scroll interaction — the user can never leave the scroll position between two snap points. proximity lets the browser decide whether to snap based on how close the final scroll position is to a snap point. If you need guaranteed alignment (carousels, slides), use mandatory. If you want natural scrolling on a long page with some snap anchors, use proximity.

Why isn’t my scroll snapping working?

The most common cause is missing overflow on the container. scroll-snap-type only works when the element actually scrolls. Add overflow-x: auto (for x axis), overflow-y: auto (for y), or overflow: auto (for both). Also confirm that your snap children have explicit sizes — if they shrink to fit their content, they may not fill the container and snapping will feel erratic.

Can I use scroll snap with Flexbox or Grid?

Yes. Flexbox and Grid are layout tools; scroll snap is a scrolling behavior overlay. Combine them freely: a horizontal flex container with overflow-x: auto and scroll-snap-type: x mandatory, where each flex child has flex: 0 0 100% and scroll-snap-align: start, is the standard carousel pattern.

What does scroll-padding actually do?

scroll-padding offsets the snap port — the rectangle on the scroll container that snap alignment is calculated against. Setting scroll-padding-top: 60px means snap points are calculated as if the container starts 60px below its actual top edge. Use this to ensure snapped items are visible and not hidden behind fixed headers or toolbars.

What is the difference between scroll-padding and scroll-margin?

scroll-padding is set on the container and insets the snap port equally for all children. scroll-margin is set on individual children and adjusts only that child’s effective snap area. In practice: use scroll-padding for global adjustments (header height), and scroll-margin for per-item tweaks (showing a peek of adjacent cards).

Should I use scroll-snap-stop?

scroll-snap-stop: always prevents fast scrolling from skipping over snap points — the browser is forced to stop at every snap point, even on a fast flick. This is useful for tutorial-style step-by-step flows where skipping steps is undesirable. For regular carousels, leave it unset (default normal) so users can flick through multiple slides in one gesture.

Related Tools

More CSS Tools