7

Building a carousel component with TailwindCSS and Alpine.js

 2 years ago
source link: https://dev.to/druidmaciek/building-a-carousel-component-with-tailwindcss-and-alpinejs-19nj
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

By the end of this article you will be able to create a carousel component with TailwindCSS and Alpine.js

Here is what a working example will look like

Set up

First add tailwind and alpine.
In the index.html add what's below to your <head>

<script src="https://unpkg.com/tailwindcss-jit-cdn"></script>

Enter fullscreen mode

Exit fullscreen mode

For Tailwind we are using the jit compiler cdn to keep it simple and keep the size small.

<script src="https://unpkg.com/alpinejs" defer></script>

Enter fullscreen mode

Exit fullscreen mode

And then the official alpine.js cdn

Creating the component

Create the main image

<body class="p-4 font-serif bg-gray-50">
    <h1 class="text-2xl font-semibold">
      TailwindCSS + Alpine.js Carousel
    </h1>
    <div class="relative">
      <img
        class="h-64 w-full object-cover object-center"
        src="https://images.unsplash.com/photo-1527549993586-dff825b37782?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80"
        alt="mountains"
      />
    </div>
</body>

Enter fullscreen mode

Exit fullscreen mode

I used mountain pics as a placeholder for the images.

previous/next buttons

Let's create to big buttons with arrows on each side to switch between items

<img class="h-64 w-full object-cover object-center"
    src="https://images.unsplash.com/photo-1527549993586-dff825b37782?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80"
    alt="mountains" />
<button
    class="absolute inset-y-0 left-0 px-2 py-[25%] h-full w-8 group hover:bg-gray-500 hover:bg-opacity-75 cursor-pointer">
    <span class="hidden group-hover:block text-gray-50">
        ←
    </span>
</button>
<button
    class="absolute inset-y-0 right-0 px-2 py-[25%] h-full w-8 group hover:bg-gray-500 hover:bg-opacity-75 cursor-pointer">
    <span class="hidden group-hover:block text-gray-50">
        →
    </span>
</button>

Enter fullscreen mode

Exit fullscreen mode

dot buttons

Next dot buttons to switch between items by index, and also show the selected item

<div class="absolute bottom-0 w-full p-4 flex justify-center space-x-2">
    <button class="h-2 w-2 rounded-full bg-gray-300 hover:bg-gray-300 ring-2 ring-gray-300"></button>
    <button class="h-2 w-2 rounded-full bg-gray-500 hover:bg-gray-300 ring-2 ring-gray-300"></button>
    <button class="h-2 w-2 rounded-full bg-gray-500 hover:bg-gray-300 ring-2 ring-gray-300"></button>
</div>

Enter fullscreen mode

Exit fullscreen mode

Your code should look like this

<div class="relative">
    <img class="h-64 w-full object-cover object-center"
        src="https://images.unsplash.com/photo-1527549993586-dff825b37782?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80"
        alt="mountains" />
    <button
        class="absolute inset-y-0 left-0 px-2 py-[25%] h-full w-8 group hover:bg-gray-500 hover:bg-opacity-75 cursor-pointer">
        <span class="hidden group-hover:block text-gray-50">
            ←
        </span>
    </button>
    <button
        class="absolute inset-y-0 right-0 px-2 py-[25%] h-full w-8 group hover:bg-gray-500 hover:bg-opacity-75 cursor-pointer">
        <span class="hidden group-hover:block text-gray-50">
            →
        </span>
    </button>
    <div class="absolute bottom-0 w-full p-4 flex justify-center space-x-2">
        <button class="h-2 w-2 rounded-full bg-gray-300 hover:bg-gray-300 ring-2 ring-gray-300"></button>
        <button class="h-2 w-2 rounded-full bg-gray-500 hover:bg-gray-300 ring-2 ring-gray-300"></button>
        <button class="h-2 w-2 rounded-full bg-gray-500 hover:bg-gray-300 ring-2 ring-gray-300"></button>
    </div>
</div>

Enter fullscreen mode

Exit fullscreen mode

Adding alpine.js

Now for the fun part let's open a script tag before the closing body tag and create our alpine object.

We need two variables:

  • selected to show a current index of image list
  • images array with the list of images we want to show in the carousel.

I will use a couple of mountain landscape images from Unsplash

const carousel = () => {
    return {
        selected: 0,
        images: [
            "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80",
            "https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80",
            "https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=987&q=80",
            "https://images.unsplash.com/photo-1486870591958-9b9d0d1dda99?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80",
            "https://images.unsplash.com/photo-1485160497022-3e09382fb310?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80",
            "https://images.unsplash.com/photo-1472791108553-c9405341e398?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2137&q=80"
        ]
    };
};

Enter fullscreen mode

Exit fullscreen mode

Next let's add x-data property to the top div of our app

<div x-data="carousel()" class="relative">

Enter fullscreen mode

Exit fullscreen mode

Showing the image

Let's make the image source show the images[selected] image.
Edit the img tag

<img class="h-64 w-full object-cover object-center" :src="images[selected]" alt="mountains" />

Enter fullscreen mode

Exit fullscreen mode

We removed the src tag and added the :src which is alpnie.js shorthand for x-bind:src

Now your image should show the first image from the images array

Next button

Let's add @click which is alpine's shorthand for x-on:click, and make it increase selected by 1 unless it's the last image then reset it back to 0

<button
    class="absolute inset-y-0 right-0 px-2 py-[25%] h-full w-8 group hover:bg-gray-500 hover:bg-opacity-75 cursor-pointer">
    <span class="hidden group-hover:block text-gray-50">
        →
    </span>
</button>

Enter fullscreen mode

Exit fullscreen mode

Previous button

The back button other way around

<button
    class="absolute inset-y-0 left-0 px-2 py-[25%] h-full w-8 group hover:bg-gray-500 hover:bg-opacity-75 cursor-pointer">
    <span class="hidden group-hover:block text-gray-50">
        ←
    </span>
</button>

Enter fullscreen mode

Exit fullscreen mode

Dot buttons

First we want to render as many buttons as there are images for that we will use the template tag and alpine x-for

<template x-for="(image,index) in images" :key="index">
    <button class="h-2 w-2 rounded-full hover:bg-gray-300 ring-2 ring-gray-300"></button>
</template>

Enter fullscreen mode

Exit fullscreen mode

Add @click to set the new index

<template x-for="(image,index) in images" :key="index">
    <button @click="selected = index" class="h-2 w-2 rounded-full hover:bg-gray-300 ring-2 ring-gray-300"></button>
</template>

Enter fullscreen mode

Exit fullscreen mode

Finally add conditional styling so the button for selected image looks different

<template x-for="(image,index) in images" :key="index">
    <button @click="selected = index" :class="{'bg-gray-300': selected == index, 'bg-gray-500': selected != index}"
        class="h-2 w-2 rounded-full hover:bg-gray-300 ring-2 ring-gray-300"></button>
</template>

Enter fullscreen mode

Exit fullscreen mode

Now your component is fully working

What's next?

You could further improve the carousel component by:

  • making it mobile responsive
  • adding animation on image change
  • auto changing the image on interval

Or you can start using the carousel in your projects.

Follow me on Twitter @MaciejJanowski to stay updated on my content.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK