CSS Scroll Snap
Create controlled, polished scrolling experiences that snap to specific positions using scroll-snap-type and scroll-snap-align.
Overview
Key Points
- •scroll-snap-type goes on the scroll container (overflow: scroll/auto required)
- •mandatory always snaps to the nearest snap point; proximity snaps only when close
- •scroll-snap-align: center is best for carousels (child centers in viewport)
- •scroll-snap-align: start is best for full-page sections
- •scroll-padding-top on the container offsets snap for sticky headers
- •scroll-snap-stop: always prevents users from skipping items in mandatory mode
- •Use scroll-behavior: smooth on html for smooth keyboard scrolling
Examples
Horizontal card carousel with snap
.carousel {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
gap: 16px;
padding: 16px;
scrollbar-width: none; /* hide scrollbar in Firefox */
}
.carousel::-webkit-scrollbar { display: none; } /* Chrome/Safari */
.carousel-item {
flex: 0 0 80%; /* item takes 80% of container width */
scroll-snap-align: center;
border-radius: 16px;
}flex: 0 0 80% prevents the item from growing or shrinking. Combining with scroll-snap-align: center creates a peek-at-next-card effect.
Full-page vertical scroll sections
.full-page-scroll {
height: 100dvh;
overflow-y: scroll;
scroll-snap-type: y mandatory;
}
.page-section {
height: 100dvh; /* each section fills the viewport */
scroll-snap-align: start; /* top edge snaps to container top */
display: flex;
align-items: center;
justify-content: center;
}Scroll padding for sticky header offset
/* Sticky header is 64px tall */
.scroll-container {
scroll-snap-type: y mandatory;
scroll-padding-top: 64px; /* offset snap by header height */
overflow-y: auto;
height: 100dvh;
}
.section {
scroll-snap-align: start;
padding-top: 64px; /* space for header */
}Without scroll-padding, content would snap behind the sticky header.
Common Mistakes
- Forgetting overflow on the scroll container scroll-snap-type has no effect without overflow: scroll or overflow: auto
- Using scroll-snap-type on the whole page body without height the body needs a defined height to scroll
- Setting mandatory without ensuring items are large enough if gaps exceed the container, the browser may not find a valid snap point
Note
Add scrollbar-width: none (Firefox) and .container::-webkit-scrollbar { display: none } (Chrome) to create a clean touch-like carousel. Users can still scroll by swiping or dragging.
Exercises
Write CSS to style the HTML scaffold. The preview updates live — when it looks right, mark as done.
Completed: 0 / 5 exercises
Knowledge Check
Question 1 of 4