How to make a card carousel with CSS & JS
Lens
Posted on January 12, 2023
Table of contents
How it works
This blog might be a bit complicated so here's an overview of how it works. We'll be making a carousel with cards (that are just div with images) and a div called card-selector. The card selector will reveal the card that the user chooses to see using the left and right buttons. To illustrate what I just said look at the gif below. The blue box is the card carousel and the red box is the card selector. The card selector or red box is where the card will be shown, so to make sure the others aren't seen yet we just set the card selectors overflow
to hidden
and on the codepen below you can see the results.
HTML and CSS
First, we'll go over the basic HTML and CSS needed. In the body element, we'll make a main element to group all the content together. In it is first a header, a left and right icon, and a div in between those icons that have a class called card-selector
. This div will be used to show only the card that was selected. Inside the card selector is an unordered list with the class of carousel
since it'sour carousel. Lastly inside the carousel are the carousel slides that have the cards, the first carousel slide will have the shownCard
class so it's the first card shown, it'll also be useful for the javascript later.
<main>
<h1>5 things i like</h1>
<ion-icon name="chevron-back-outline" class="button-backwards"></ion-icon>
<div class="card-selector">
<ul class="carousel">
<li class="carousel_slide shownCard">
<div id="Cards" class="firstCard"></div>
</li>
<li class="carousel_slide">
<div id="Cards" class="secondCard"></div>
</li>
<li class="carousel_slide">
<div id="Cards" class="thirdCard"></div>
</li>
<li class="carousel_slide"><div id="Cards" class="fourthCard">
</div></li>
<li class="carousel_slide">
<div id="Cards" class="fifthCard"></div>
</li>
</ul>
</div>
<ion-icon name="chevron-forward-outline" class="button-forward"></ion-icon>
</main>
For the CSS we center everything by giving the body a display
of flex
and giving align-items
and justify-content
a value of center
. For my ul element or carousel, we give it a width
and height
of 250px
and a display
of flex
to center the cards. We also set the list-style-type
to none so we don't have those li discs remaining in it. We give the carousel slides a position of absolute while giving the carousel a position relative to stack the slides on top of each other. We make the slides the same size as the card container and give them flex to center their div cards. We'll also make sure they're in the container by setting their top
and bottom
to 0
. The left and right buttons have an absolute position to use the top
left
and right
properties to place them. Finally, I gave each card a background-image
.
.card-selector {
margin: 0 auto;
padding: 0;
border: solid 2px red;
}
.carousel {
position: relative;
}
.carousel_slide {
position: absolute;
top: 0;
bottom: 0;
width: 250px;
height: 250px;
display: flex;
align-items: center;
justify-content: center;
border: solid 2px blue;
}
/*Styling the buttons*/
ion-icon {
font-size: 40px;
position: absolute;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
z-index: 3;
color: white;
}
.button-backwards {
left: 30%;
top: 50%;
}
.button-forward {
right: 30%;
top: 50%;
}
/*Styling the cards*/
#Cards {
width: 100px;
height: 150px;
transition: 0.4s;
background-size: cover;
}
}
Javacript
First, we make variables containing the carousel and button, we also make a variable with an array of the carousel's children, this is how we get all the carousel slides. Another variable we'll make is a variable called cardSize
which has the width boundingClientReact of the cards. The BoundingClientReact is a method used to get information and the size width and height of an element, so since we gave the cardSize variable a value of cards[0].getBoundingClientReact().width
we now stored the width of the slides in that variable.
var carousel = document.querySelector('.carousel');
var carousel_slide = Array.from(carousel.children);
var nextButton = document.querySelector('.button-forward');
var backButton = document.querySelector('.button-backwards');
var cardSize = carousel_slide[0].getBoundingClientRect().width;
The cards will now have a forEach
method where in it is an arrow function that stylizes the left property value of the carousel slides to be the cardSize variable * the index. This makes it so the carousel slides aren't on top of each other but are side by side. Here's an image to show you, the blue boxes are the carousel slides.
carousel_slide.forEach((slide, index) => {
slide.style.left = cardSize * index + 'px';
})
Now for the buttons, we'll make an arrow function called moveToCard
with the carousel, targetCard
and currentCard
being its parameters to shorten the code for the event listeners of the buttons. The target card will be the card that'll be shown next, while the current card is the card that's being seen. We'll make it so the card container translates on the X-axis by the left property value of the target card. Next, we make it so the shownCard class will be removed from the current card and will be added to the target card so the function can run more than once.
const moveToCard = (carousel, currentCard, targetCard) => {
carousel.style.transform = 'translateX(-' + targetCard.style.left + ')';
currentCard.classList.remove('shownCard');
targetCard.classList.add('shownCard');
}
Next, we'll make the button event listeners that'll use the MovetoCard function. We make two variables with one having the shownCard class and the other being the target card. The target card in each event listener will be different because the next button's event listener will have the current card's nextElementSibling
while the previous button will have the current card's previousElementSibling
. Finally, we call the function with the currentCard parameter being the variable with the shownCard class and the targetCard being the card with the currentCard's sibling.
nextButton.addEventListener('click', function() {
const currentCard = document.querySelector('.shownCard');
const targetCard = currentCard.nextElementSibling;
moveToCard(carousel, currentCard, targetCard);
});
backButton.addEventListener('click', function() {
const currentCard = document.querySelector('.shownCard');
const prevCard = currentCard.previousElementSibling;
moveToCard(carousel, currentCard, prevCard);
});
Now when we click the forward/next button we go to the current cards next element sibling wich becomes the current card. If we click the previous button we go to the previous carousel slide element wich becomes the current card. Now that we made the card carousel we can make cool transitions and effects.
Hover effects
We gave each card a hover effect where their before pseudo-element goes from invisible to visible. We did this by setting the before pseudo-class to display: none;
but when the card is hovered, it'll transition up. Lastly, we gave each card a different content based on how they look.
.carousel_slide > div::before {
display: none;
}
.carousel_slide > div:hover::before {
position: relative;
top: 170px;
left: 24px;
color: white;
font-size: 20px;
transition: 0.5s;
display: block;
font-family: 'Courier New', Courier, monospace;
}
Color change JS
This section is about how i made it so when you click a card the color of the website changes. First we put all the cards in a variable as an array. Then we give each card an event listener where when their clicked, they'll change the background-color to a certain color that matches their card.
var card = Array.from(document.querySelectorAll('#Cards'));
card[0].addEventListener('click', function() {
document.body.style.backgroundColor = '#FADBBEff';
})
card[1].addEventListener('click', function() {
document.body.style.backgroundColor = '#bc6c25';
})
card[2].addEventListener('click', function() {
document.body.style.background = '#6905BBff';
})
card[3].addEventListener('click', function() {
document.body.style.background = '#2a9d8f';
})
card[4].addEventListener('click', function() {
document.body.style.backgroundColor = '#ff7d00';
})
Conclusion
Even though i started making this blog a week ago it took so long because of the way i named by variables and classes since they were confusing and irrelavent to their actual use, but after a while i fixed the code so it can be easier for you to understand. I'm also sorry if this blog is too long or complicated, so if you have an questions or want change's in my blog please tell them in the comments! You can also show me the card carousel you made in the comments, so with all said and done i hope you have a great day or night!
Posted on January 12, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.