Building a carousel component with TailwindCSS and Alpine.js
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.
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.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK