Building Responsive Carousels with Tailwind CSS (+Examples)

Learn how to build responsive carousels using Tailwind CSS.

by Yucel Faruk Sahan
8 min read
Updated on

This guide will walk you through each step, whether you're an experienced developer or a beginner. By the end, you'll have a working carousel that looks great on any device.

Let's get started!

Setting up Tailwind Project (if you haven't done so yet)

To get started, you'll need to set up a new project with Tailwind CSS. If you haven't already, you'll need Node.js and npm installed on your machine. Here's a quick rundown of the setup process:

  1. Initialize a New Project:

    npm init -y
  2. Install Tailwind CSS:

    npm install tailwindcss
  3. Create Tailwind Configuration:

    npx tailwindcss init
  4. Configure Tailwind: Open the tailwind.config.js file and set up your content paths:

    module.exports = {
      content: ["./src/**/*.{html,js}"],
      theme: {
        extend: {},
      },
      plugins: [],
    }
  5. Create CSS File: Create a styles.css file and add the following:

    @tailwind base;
    @tailwind components;
    @tailwind utilities;
  6. Build Tailwind CSS: Add a build script to your package.json:

    "scripts": {
      "build": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --watch"
    }

    Then run the build script:

    npm run build

Now that we have Tailwind CSS set up, let's build the basic structure of our carousel. We'll start with the HTML:

<div class="carousel relative overflow-hidden">
  <div class="carousel-inner relative w-full overflow-hidden">
    <div class="carousel-item active absolute w-full">
      <img src="image1.jpg" class="block w-full" alt="Slide 1">
    </div>
    <div class="carousel-item absolute w-full">
      <img src="image2.jpg" class="block w-full" alt="Slide 2">
    </div>
    <!-- Add more slides as needed -->
  </div>
  <!-- Carousel Controls -->
  <button class="carousel-prev absolute top-1/2 left-0 transform -translate-y-1/2">
    &lt;
  </button>
  <button class="carousel-next absolute top-1/2 right-0 transform -translate-y-1/2">
    &gt;
  </button>
</div>
Example Image Cards

Image Placeholder: bg-yellow-100

Image Placeholder: bg-green-100

Image Placeholder: bg-blue-100

Image Placeholder: bg-pink-100

Adding Tailwind CSS Classes

To make our carousel responsive and visually appealing, we'll add some Tailwind CSS classes. Here's how we can enhance the carousel:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Carousel</title>
  <style>
    .carousel { position: relative; width: 100%; }
    .carousel-inner { position: relative; width: 100%; height: 300px; }
    .carousel-item { position: absolute; width: 100%; transition: transform 0.5s ease; }
    .carousel-item img { width: 100%; height: auto; }
    .carousel-prev, .carousel-next { cursor: pointer; font-size: 2rem; }
  </style>
</head>
<body>
  <div class="carousel relative overflow-hidden">
    <div class="carousel-inner relative w-full overflow-hidden">
      <div class="carousel-item active absolute w-full">
        <img src="image1.jpg" class="block w-full" alt="Slide 1">
      </div>
      <div class="carousel-item absolute w-full">
        <img src="image2.jpg" class="block w-full" alt="Slide 2">
      </div>
      <!-- Add more slides as needed -->
    </div>
    <!-- Carousel Controls -->
    <button class="carousel-prev absolute top-1/2 left-0 transform -translate-y-1/2">
      &lt;
    </button>
    <button class="carousel-next absolute top-1/2 right-0 transform -translate-y-1/2">
      &gt;
    </button>
  </div>
</body>
</html>

To make the carousel functional, we'll need a bit of JavaScript. Let's add some basic JavaScript to handle the slide transitions:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Carousel</title>
  <style>
    .carousel { position: relative; width: 100%; }
    .carousel-inner { position: relative; width: 100%; height: 300px; }
    .carousel-item { position: absolute; width: 100%; transition: transform 0.5s ease; }
    .carousel-item img { width: 100%; height: auto; }
    .carousel-prev, .carousel-next { cursor: pointer; font-size: 2rem; }
  </style>
</head>
<body>
  <div class="carousel relative overflow-hidden">
    <div class="carousel-inner relative w-full overflow-hidden">
      <div class="carousel-item active absolute w-full">
        <img src="image1.jpg" class="block w-full" alt="Slide 1">
      </div>
      <div class="carousel-item absolute w-full">
        <img src="image2.jpg" class="block w-full" alt="Slide 2">
      </div>
      <!-- Add more slides as needed -->
    </div>
    <!-- Carousel Controls -->
    <button class="carousel-prev absolute top-1/2 left-0 transform -translate-y-1/2">
      &lt;
    </button>
    <button class="carousel-next absolute top-1/2 right-0 transform -translate-y-1/2">
      &gt;
    </button>
  </div>

  <script>
    document.addEventListener('DOMContentLoaded', function () {
      const carouselInner = document.querySelector('.carousel-inner');
      const carouselItems = document.querySelectorAll('.carousel-item');
      const prevButton = document.querySelector('.carousel-prev');
      const nextButton = document.querySelector('.carousel-next');
      let currentIndex = 0;

      function updateCarousel() {
        carouselItems.forEach((item, index) => {
          item.style.transform = `translateX(${(index - currentIndex) * 100}%)`;
        });
      }

      prevButton.addEventListener('click', () => {
        currentIndex = (currentIndex > 0) ? currentIndex - 1 : carouselItems.length - 1;
        updateCarousel();
      });

      nextButton.addEventListener('click', () => {
        currentIndex = (currentIndex < carouselItems.length - 1) ? currentIndex + 1 : 0;
        updateCarousel();
      });

      updateCarousel();
    });
  </script>
</body>
</html>

Tailwind CSS makes it easy to customize the look and feel of your carousel. Here are a few ideas to get you started:

Customizing Controls

You can further customize the carousel controls to match your design. For example, you can change the background color, size, or add icons:

<button class="carousel-prev absolute top-1/2 left-0 transform -translate-y-1/2 bg-blue-500 text-white p-3 rounded-full">
  <svg xmlns="<http://www.w3.org/2000/svg>" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
  </svg>
</button>
<button class="carousel-next absolute top-1/2 right-0 transform -translate-y-1/2 bg-blue-500 text-white p-3 rounded-full">
  <svg xmlns="<http://www.w3.org/2000/svg>" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
  </svg>
</button>

Adding Indicators

Indicators can help users know which slide they're on. Here's how you can add them:

<div class="carousel-indicators flex justify-center mt-4">
  <button class="indicator w-3 h-3 bg-gray-400 rounded-full mx-1" data-slide-to="0"></button>
  <button class="indicator w-3 h-3 bg-gray-400 rounded-full mx-1" data-slide-to="1"></button>
  <!-- Add more indicators as needed -->
</div>

<script>
  const indicators = document.querySelectorAll('.indicator');
  indicators.forEach((indicator, index) => {
    indicator.addEventListener('click', function() {
      currentIndex = index;
      updateCarousel();
    });
  });

  function updateIndicators() {
    indicators.forEach((indicator, index) => {
      indicator.classList.toggle('bg-gray-800', index === currentIndex);
      indicator.classList.toggle('bg-gray-400', index !== currentIndex);
    });
  }

  updateCarousel = function() {
    items.forEach((item, index) => {
      item.classList.remove('active');
      item.style.transform = `translateX(${(index - currentIndex) * 100}%)`;
    });
    items[currentIndex].classList.add('active');
    updateIndicators();
  }
</script>
setInterval(() => {
  currentSlide = (currentSlide + 1) % slides.length;
  showSlide(currentSlide);
}, 5000); // Change slide every 5 seconds

Just change the flex direction to column and adjust the transform property accordingly:

<div class="flex flex-col transition-transform duration-300 ease-in-out">
  <!-- Vertical slides here -->
</div>
<div class="absolute bottom-2 left-0 right-0 flex justify-center">
  <span class="h-2 w-2 bg-white rounded-full mx-1"></span>
  <span class="h-2 w-2 bg-gray-300 rounded-full mx-1"></span>
  <span class="h-2 w-2 bg-gray-300 rounded-full mx-1"></span>
</div>

Can I use Tailwind CSS to create infinite scroll carousels?

Yes, you can! It involves cloning the first and last slides and adjusting the JavaScript logic. Here's a basic approach:

function infiniteScroll() {
  if (currentSlide > slides.length) {
    currentSlide = 1;
    carousel.style.transition = 'none';
    showSlide(currentSlide);
  } else if (currentSlide < 1) {
    currentSlide = slides.length;
    carousel.style.transition = 'none';
    showSlide(currentSlide);
  }
}

Conclusion

Building a responsive carousel with Tailwind CSS is not only possible but also incredibly straightforward. With Tailwind's utility-first approach, you can create a visually appealing and highly customizable carousel that fits perfectly into your design.