New CSS carousel features let a scroll container generate previous/next buttons and markers. The browser keeps them in sync with scroll snap, which removes a surprising amount of JavaScript.
.carousel {
display: flex;
gap: 1rem;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-marker-group: after;
}
.carousel::scroll-button(left) {
content: '<' / 'Previous';
}
.carousel::scroll-button(right) {
content: '>' / 'Next';
}
.carousel > * {
flex: 0 0 80%;
scroll-snap-align: center;
}
.carousel > *::scroll-marker {
content: attr(data-label);
}
The newer pseudo-elements are still settling, so keep the HTML useful without them. More info on MDN.