Learn how to create polished scrolling experiences with CSS Scroll Snap. Master scroll-snap-type, scroll-snap-align, scroll-padding, and build smooth horizontal galleries and vertical page sections.
CSS Scroll Snap lets you control where a scroll container lands after the user finishes scrolling. Instead of stopping at an arbitrary position, the container snaps to predefined points, creating a polished, app-like experience.
Two properties work together:
On the scroll container:
.scroller {
scroll-snap-type: x mandatory;
}x, y, or both) sets the scroll axis.mandatory — The browser must snap to a snap point after scrolling. The user cannot rest between snap points.proximity — The browser only snaps if the scroll position is near a snap point. Allows free scrolling otherwise.On each child item:
.slide {
scroll-snap-align: start;
}Values: start, center, end, or none. This determines which edge of the item aligns with the container's snap port.
<style>
.gallery {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
gap: 16px;
padding: 16px;
background: #0f172a;
}
.gallery::-webkit-scrollbar {
height: 8px;
}
.gallery::-webkit-scrollbar-thumb {
background: #6366f1;
border-radius: 4px;
}
.slide {
flex: 0 0 280px;
height: 180px;
scroll-snap-align: center;
background: #1e293b;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 24px;
font-weight: bold;
}
</style>
<div class="gallery">
<div class="slide">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
<div class="slide">4</div>
<div class="slide">5</div>
</div>The scroll-padding property adds an offset to the snap point, which is useful when you have a fixed header or want visual breathing room:
.scroller {
scroll-snap-type: y mandatory;
scroll-padding-top: 80px; /* accounts for a fixed header */
}Vertical full-page sections are another popular scroll snap pattern:
.page-scroller {
height: 100vh;
overflow-y: auto;
scroll-snap-type: y mandatory;
}
.section {
height: 100vh;
scroll-snap-align: start;
}Each section takes the full viewport height, and scroll snap ensures the user always lands perfectly on a section boundary.
Best practices:
mandatory for carousels and full-page sections where partial views look broken.proximity for long content where the user may need to scroll freely.What is the difference between scroll-snap-type: x mandatory and scroll-snap-type: x proximity?