Tip #27: Build simple sliders with scroll snapping in TailwindCSS

  • — Frontend

  • 4 min. read

  • — 2/23/2023

You know those flick sliders you see on mobile? The ones where you kinda just swipe and the slider snaps to the next element in the container?

Basically something like this:

(this is all native CSS by the way)

Let's get started.

First let's build our section and a basic card in our grid.

<section class="flex min-h-screen items-center bg-slate-900 p-6">
  <div class="container mx-auto space-y-6">
    <h2 class="text-3xl font-semibold text-white">Our Features</h2>
    <ul class="flex snap-x snap-mandatory gap-x-6 overflow-x-auto pb-6">
        <!-- <Card> -->
      <li class="w-2/3 flex-shrink-0 snap-center">
        <div class="space-y-6 rounded-lg border border-white/30 p-6">
          <div class="flex items-center gap-x-5">
            <div class="h-12 w-12 rounded-full bg-gray-300"></div>
            <h3 class="text-xl font-medium text-white">Feature #1</h3>
          </div>
          <div class="space-y-1">
            <div class="h-4 w-10/12 bg-white/30"></div>
            <div class="h-4 w-7/12 bg-white/30"></div>
            <div class="h-4 w-8/12 bg-white/30"></div>
          </div>
        </div>
      </li>
        <!-- </Card> -->
    </ul>
  </div>
</section>

Just some quick notes here:

  • We make extensive use of gap-* and space-* utilities for easy spacing (if you are unfamiliar with these utilities, check out my post on using gaps/spaces in TailwindCSS)
  • We're using snap-x and snap-mandatory on the ul, this is how we get that "flick" effect to work
  • We're also using snap-center on the li element, this is how the slider snaps to the center of each card on scroll
  • Lastly, you'll notice how  we use a generic overflow-x-auto on the ul. This whole slider works on the assumption that we have an overflow, however the scroll behavior gets "hijacked" by the snap-x and snap-mandatory properties

Enough technical talk, let's complete the slider by adding more cards to the ul:

<section class="flex min-h-screen items-center bg-slate-900 p-6">
  <div class="container mx-auto space-y-6">
    <h2 class="text-3xl font-semibold text-white">Our Features</h2>
    <ul class="flex snap-x snap-mandatory gap-x-6 overflow-x-auto pb-6">
      <li class="w-2/3 flex-shrink-0 snap-center">
        <div class="space-y-6 rounded-lg border border-white/30 p-6">
          <div class="flex items-center gap-x-5">
            <div class="h-12 w-12 rounded-full bg-gray-300"></div>
            <h3 class="text-xl font-medium text-white">Feature #1</h3>
          </div>
          <div class="space-y-1">
            <div class="h-4 w-10/12 bg-white/30"></div>
            <div class="h-4 w-7/12 bg-white/30"></div>
            <div class="h-4 w-8/12 bg-white/30"></div>
          <!-- </div> -->
        </div>
      </li>
      <li class="w-2/3 flex-shrink-0 snap-center">
        <div class="space-y-6 rounded-lg border border-white/30 p-6">
          <div class="flex items-center gap-x-5">
            <div class="h-12 w-12 rounded-full bg-gray-300"></div>
            <h3 class="text-xl font-medium text-white">Feature #2</h3>
          </div>
          <div class="space-y-1">
            <div class="h-4 w-10/12 bg-white/30"></div>
            <div class="h-4 w-7/12 bg-white/30"></div>
            <div class="h-4 w-8/12 bg-white/30"></div>
          </div>
        </div>
      </li>
      <li class="w-2/3 flex-shrink-0 snap-center">
        <div class="space-y-6 rounded-lg border border-white/30 p-6">
          <div class="flex items-center gap-x-5">
            <div class="h-12 w-12 rounded-full bg-gray-300"></div>
            <h3 class="text-xl font-medium text-white">Feature #3</h3>
          </div>
          <div class="space-y-1">
            <div class="h-4 w-10/12 bg-white/30"></div>
            <div class="h-4 w-7/12 bg-white/30"></div>
            <div class="h-4 w-8/12 bg-white/30"></div>
          </div>
        </div>
      </li>
      <li class="w-2/3 flex-shrink-0 snap-center">
        <div class="space-y-6 rounded-lg border border-white/30 p-6">
          <div class="flex items-center gap-x-5">
            <div class="h-12 w-12 rounded-full bg-gray-300"></div>
            <h3 class="text-xl font-medium text-white">Feature #4</h3>
          </div>
          <div class="space-y-1">
            <div class="h-4 w-10/12 bg-white/30"></div>
            <div class="h-4 w-7/12 bg-white/30"></div>
            <div class="h-4 w-8/12 bg-white/30"></div>
          </div>
        </div>
      </li>
    </ul>
  </div>
</section>

And... we're done 🎉. Seriously that's all it takes to build a really simple flick slider in TailwindCSS.

Here's the final result:

Psst... to hide that ugly scrollbar, use the ::-webkit-scrollbar psuedo-selector in a custom CSS file and select the ul (or whichever element has overflow-x-auto

ul::-webkit-scrollbar{
    display: none;
}
Shaun Chander

hey (again), I'm shaun

I'm posting 3 tips on creative web development daily. Subscribe below to to get tips delivered straight into your inbox!