HTML carousels are a bad thing, that is already written, but I’ve also noticed that they are not going to leave us, because designers love them and product owners love them. So I end up liking a lot a different approach taken by “Javier Villanueva” in his article about making sure at least they don’t kill the site performance.

In his article he presents the way to have a slider using css only. That way is great, but I found it is quite challenging to display more than a single slide for what we call a carousel, I found a solution for that, and will share it here.

<div class="grid">
  <div class="item">bla</div>
  <div class="item">ble</div>
  <div class="item">blbblbk</div>
  <div class="item">more</div>
  <div class="item">a</div>
  <div class="item">noknmlsd</div>
  <div class="item">ksldf</div>
</div>
.grid {
  --gap: 0.5rem;
  --slides: 5;
  display: grid;
  grid: auto / auto-flow calc((100% + var(--gap)) / var(--slides) - var(--gap));
  background: #16d15642;
  border: #16d156 solid 1px;
  padding: calc(var(--gap) + 0.5px);
  gap: calc(var(--gap) + 0.5px);
  max-width: 400px;
  margin: 1rem auto;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: var(--gap);
}

.item {
border: solid 1px #666;
background: hsla(250, 80%, 40%, 0.2);
padding: 0.5rem;
scroll-snap-align: start;
}

The problem is that the gap between slides makes it quite hard to get the right width for each item to get an integer numbers of items per view. So the width is the result of a big calc that solves. As it is using variables you can dynamically (or manually) change the number of slides per view.

As I’m using scroll-snap-align: start, it also requires adding scroll-padding to the parent, and finally there is some rounding error that makes it required to add half a pixel to the actual padding and gap.