
Building Smooth Carousels with Native CSS Scroll Snap
Traditional JavaScript carousel libraries add tens of kilobytes of bundle weight, hijack native browser scrolling, and frequently feel sluggish on mobile touchscreens. With the CSS Scroll Snap specification supported across modern evergreen browsers, you can build smooth, hardware-accelerated horizontal galleries with just two lines of CSS.
Example
.carousel-track {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.carousel-slide {
scroll-snap-align: start;
}
Input : Horizontal flex list of cards or images
Output : Native touch and trackpad carousel that snaps cleanly to each card boundary.
Implementation
<section aria-label="Featured Articles Carousel">
<ul class="snap-carousel">
<li class="snap-carousel__item">
<article class="card">
<h3>Semantic HTML5</h3>
<p>Structure documents for screen readers and search engines.</p>
</article>
</li>
<li class="snap-carousel__item">
<article class="card">
<h3>CSS Grid Systems</h3>
<p>Build two-dimensional responsive layouts cleanly.</p>
</article>
</li>
<li class="snap-carousel__item">
<article class="card">
<h3>Vanilla JavaScript</h3>
<p>Keep runtime bundles fast and dependency-free.</p>
</article>
</li>
</ul>
</section>
.snap-carousel {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
list-style: none;
padding: 0 0 16px 0;
margin: 0;
}
.snap-carousel__item {
flex: 0 0 85%;
max-width: 360px;
margin-right: 20px;
scroll-snap-align: start;
}
.snap-carousel__item .card {
border: 1px solid #dedede;
padding: 24px;
height: 100%;
}
Main Point: Setting flex: 0 0 85% on mobile lets a sliver of the next card peek into view, giving users a clear visual affordance that the container scrolls horizontally.
Credits
Photo by Paul Esch-Laurent