How to make a carousel with scroll-snap
Short answer
Horizontal scrolling plus snapping to the slides. Swipe, use the wheel with Shift or the scrollbar:
<style>
.slider { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 8px; }
.slider img { flex: 0 0 80%; width: 80%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 10px; scroll-snap-align: center; }
</style>
<div class="slider">
<img src="/media/photo-800x500.jpg" alt="Slide 1">
<img src="/media/photo-400x250.jpg" alt="Slide 2">
<img src="/media/photo-600x200.jpg" alt="Slide 3">
</div>How it works
scroll-snap-type: x mandatory on the container says it must stop at a snap point after scrolling. scroll-snap-align: center makes the center of each slide such a point. Slides at 80% width show the edge of the next one, so it is clear there is more.
Buttons and dots
Links to slide ids scroll to the right one without a script. "Next" and "previous" buttons need a short script with scrollBy(). In new browsers the ::scroll-button() and ::scroll-marker pseudo-elements draw buttons and dots, but they are not supported everywhere yet.
Common mistake
A carousel that scrolls on its own. Users cannot finish reading a slide, and it gets in the way of people with attention difficulties and screen reader users. If you really need autoplay, add a pause button and stop it on hover and focus.
Functions used in this recipe
- scroll-snap-type — Makes a scrolling container stop exactly at its children — for sliders and galleries.
- overflow — What to do with content that does not fit into the element.
- flex — A shorthand for how a flex item grows, shrinks and what size it starts from.