NoLoJS logo

CSS Carousel - Swipe by Groups

If swiping “by groups”, or an implicit number of slides, is ever desired, all CSS, no JS required.

Demo

HTML

<!-- No special HTML -->
<ul class="css-carousel">
  <li>Slide 1</li>
  <li>Slide 2</li>
  <li>Slide 3</li>
  <li>Slide 4</li>
  <li>Slide 5</li>
  <li>Slide 6</li>
  <li>Slide 7</li>
  <li>Slide 8</li>
  <li>Slide 9</li>
  <li>Slide 10</li>
  <li>Slide 11</li>
  <li>Slide 12</li>
</ul>

CSS

/* Basic carousel CSS */
.css-carousel {
  /* Resets for carousel appearance */
  list-style: none;
  padding: 0;
  /* The only CSS necessary for a simple swiper Carousel */
  display: flex;
  overflow-inline: auto;
  /* Prevents accidental page Back/Forward */
  overscroll-behavior-inline: contain;
  /* Confines the scrolling direction */
  scroll-snap-type: inline mandatory;
  /* Be nice to others */
  @media (prefers-reduced-motion: no-preference) { 
    /* Makes the sliding a little smoother */
    scroll-behavior: smooth;
  }
  
/** Create "groups" to swipe **/
  /* Override Flex from above, breaks this functionality */
  display: block;
  /* The Carousel container needs an explicit height to force overflow */
  max-height: 200px;
  /* Sets the column scope */
  columns: 1;
  /* Aligns the slides within the column */
  text-align: center;
  
  li {
    /* Make things look a little nicer */
    min-width: 200px;
    aspect-ratio: 1 / 1;
    border: 1px solid;
    place-content: center;
    text-align: center;
    /* Allow slides to sit side-by-side */
    display: inline-block;
  }

  &::column {
  /* Snap each scroll to the center of the column */
    scroll-snap-align: center;
  }
}

JS

No JS required.

Baseline

[`scroll-behavior`](https://webstatus.dev/features/scroll-behavior) [`scroll-snap`](https://webstatus.dev/features/scroll-snap) [`column-pseudo`](https://webstatus.dev/features/column-pseudo)

CodePen

See the Pen on CodePen.