How to Use Scroll Snap in CSS for Smooth Scrolling
Use
scroll-snap-type on a container to define the snapping behavior and scroll-snap-align on child elements to specify snap positions. This makes scrolling stop at defined points smoothly and predictably.Syntax
scroll-snap-type sets the scroll container's snapping behavior. It takes two parts: the axis (x, y, or both) and the snapping strictness (mandatory or proximity).
scroll-snap-align defines how child elements align when snapping. Common values are start, center, and end.
css
/* Container */ .scroll-container { scroll-snap-type: x mandatory; /* horizontal snap, mandatory */ overflow-x: scroll; display: flex; } /* Child elements */ .scroll-item { scroll-snap-align: start; /* snap at the start edge */ }
Example
This example shows a horizontal scroll container with three colored boxes that snap to the start of the container when scrolling.
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> .scroll-container { scroll-snap-type: x mandatory; overflow-x: auto; display: flex; width: 100%; border: 2px solid #333; } .scroll-item { scroll-snap-align: start; flex: 0 0 80%; height: 150px; margin-right: 20px; border-radius: 8px; color: white; font-size: 1.5rem; display: flex; align-items: center; justify-content: center; } .item1 { background-color: #e63946; } .item2 { background-color: #457b9d; } .item3 { background-color: #2a9d8f; } </style> </head> <body> <div class="scroll-container" tabindex="0" aria-label="Scrollable color boxes"> <div class="scroll-item item1">Box 1</div> <div class="scroll-item item2">Box 2</div> <div class="scroll-item item3">Box 3</div> </div> </body> </html>
Output
A horizontal scroll area with three colored boxes side by side. When you scroll horizontally, the view snaps so each box aligns at the left edge smoothly.
Common Pitfalls
- Not setting
overflowon the container prevents scrolling and snapping. - Using
scroll-snap-typewithout specifying axis or strictness can cause unexpected behavior. - For snapping to work, child elements must have
scroll-snap-alignset; otherwise, snapping points are undefined. - Horizontal snapping requires
display: flexor fixed widths on children to align properly.
css
/* Wrong: Missing overflow, no scroll */ .scroll-container { scroll-snap-type: x mandatory; /* overflow-x missing */ display: flex; } /* Right: Add overflow-x to enable scrolling */ .scroll-container { scroll-snap-type: x mandatory; overflow-x: auto; display: flex; }
Quick Reference
| Property | Purpose | Common Values |
|---|---|---|
| scroll-snap-type | Defines scroll snapping on container | none, x, y, both + mandatory, proximity |
| scroll-snap-align | Defines snap position on child | start, center, end |
| overflow-x / overflow-y | Enables scrolling on container | auto, scroll |
| display | Layout for children (often flex for horizontal) | flex, block |
Key Takeaways
Set scroll-snap-type on the container to enable snapping and define axis and strictness.
Use scroll-snap-align on child elements to specify where they snap in the viewport.
Always enable scrolling with overflow-x or overflow-y on the container.
Use flex layout or fixed widths for horizontal snapping to work smoothly.
Test scroll snapping on real devices or browsers as behavior can slightly vary.