There are times when we only need CSS and JS to handle a carousel. This tutorial shows you how to create a sleek and responsive carousel from scratch, without relying on any external libraries.
Perfect for web developers looking to enhance their skills and add dynamic, interactive elements to their websites. Learn how to implement smooth transitions, responsive design, and user-friendly navigation. Whether you're a beginner or an experienced developer, this guide provides clear, step-by-step instructions to help you master the art of creating a pure CSS and JS carousel.
DEMO: You can find demo at JSFiddle
1. HTML code
This structure allows for a visually appealing and interactive carousel with multiple cards, each containing a title, subtitle, and image. The navigation dots at the bottom help users navigate through the carousel items.
<div class="section-activity">
<div class="carousel-wrapper">
<div class="activity-group">
<div class="card">
<div class="card-top">
<div class="title">
<div class="heading">
Lorem Ipsum
</div>
<div class="sub">
The lorem tag inserts a specified amount of random text. The "random" text is the famous "Lorum ipsum" text, in lower case letters.
</div>
</div>
<div class="image">
<img src="https://news-1hour-dev.s3.us-east-2.amazonaws.com/posts/6693e22e4119fc3d30ada52f/a2.jpg" alt="">
</div>
</div>
</div>
<div class="card">
<div class="card-top">
<div class="title">
<div class="heading">
Lorem Ipsum
</div>
<div class="sub">
The lorem tag inserts a specified amount of random text. The "random" text is the famous "Lorum ipsum" text, in lower case letters.
</div>
</div>
<div class="image">
<img src="https://news-1hour-dev.s3.us-east-2.amazonaws.com/posts/667a19cc82610cd8cb4fcf47/2.jpg" alt="">
</div>
</div>
</div>
<div class="card">
<div class="card-top">
<div class="title">
<div class="heading">
Lorem Ipsum
</div>
<div class="sub">
The lorem tag inserts a specified amount of random text. The "random" text is the famous "Lorum ipsum" text, in lower case letters.
</div>
</div>
<div class="image">
<img src="https://news-1hour-dev.s3.us-east-2.amazonaws.com/posts/667a19cc82610cd8cb4fcf47/1.jpg" alt="">
</div>
</div>
</div>
<div class="card">
<div class="card-top">
<div class="title">
<div class="heading">
Lorem Ipsum
</div>
<div class="sub">
The lorem tag inserts a specified amount of random text. The "random" text is the famous "Lorum ipsum" text, in lower case letters.
</div>
</div>
<div class="image">
<img src="https://news-1hour-dev.s3.us-east-2.amazonaws.com/posts/667a19cc82610cd8cb4fcf47/1.jpg" alt="">
</div>
</div>
</div>
<div class="card">
<div class="card-top">
<div class="title">
<div class="heading">
Lorem Ipsum
</div>
<div class="sub">
The lorem tag inserts a specified amount of random text. The "random" text is the famous "Lorum ipsum" text, in lower case letters.
</div>
</div>
<div class="image">
<img src="https://news-1hour-dev.s3.us-east-2.amazonaws.com/posts/667a19cc82610cd8cb4fcf47/1.jpg" alt="">
</div>
</div>
</div>
<div class="card">
<div class="card-top">
<div class="title">
<div class="heading">
Lorem Ipsum
</div>
<div class="sub">
The lorem tag inserts a specified amount of random text. The "random" text is the famous "Lorum ipsum" text, in lower case letters.
</div>
</div>
<div class="image">
<img src="https://news-1hour-dev.s3.us-east-2.amazonaws.com/posts/667a19cc82610cd8cb4fcf47/3.jpg" alt="">
</div>
</div>
</div>
</div>
</div>
<div class="dots">
<div class="dot active"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
</div>
2. CSS
This CSS code ensures a responsive and visually appealing carousel with smooth transitions and interactive elements.
.section-activity {
justify-content: center;
background: var(--background-bw-white, #fff);
background-color: var(--background-bw-white, #fff);
display: flex;
flex-direction: column;
align-items: center;
}
.carousel-wrapper {
margin-top: 24px;
overflow: hidden;
width: 100%;
}
.carousel-wrapper .activity-group {
display: flex;
margin: 0 auto;
max-width: 1220px;
transition: transform 0.5s ease;
}
.carousel-wrapper .activity-group .card {
flex: 0 0 100%;
max-width: calc(50% - 24px);
box-sizing: border-box;
border-radius: 20px;
background-color: rgba(252, 252, 253, 1);
display: flex;
min-width: 240px;
flex-direction: column;
justify-content: start;
border: 2px solid rgba(204, 212, 255, 1);
padding: 16px;
margin: 0 12px;
}
.carousel-wrapper .activity-group .card .card-top {
display: flex;
gap: 16px;
}
.carousel-wrapper .activity-group .card .card-top .image{
width: 30%;
}
.carousel-wrapper .activity-group .card .card-top img{
width: 100%;
height: 80px;
border-radius: 12px;
object-fit: cover;
}
.carousel-wrapper .activity-group .card .title {
width: 70%;
display: flex;
flex-direction: column;
gap: 8px;
max-width: 400px;
}
.carousel-wrapper .activity-group .card .title .heading {
font-size: 21px;
overflow: hidden;
text-overflow: ellipsis; /* Thêm dấu ba chấm */
font-weight: 600;
font-family: var(--family-title);
}
.carousel-wrapper .activity-group .card .title .sub {
font-size: 14px;
font-weight: 500;
line-height: 19.6px;
font-family: var(--family-text);
color: var(--text-color);
overflow: hidden;
text-overflow: ellipsis; /* Thêm dấu ba chấm */
}
.carousel-wrapper .activity-group .card .detail {
padding: 10px 0;
display: flex;
gap: 4px;
width: 129px;
cursor: pointer;
font-family: var(--family-title);
font-weight: 500;
font-size: 16px;
line-height: 24px;
}
.carousel-wrapper .activity-group .card .detail button {
border: none;
background-color: #ffffff;
}
.section-activity .dots {
align-self: center;
display: flex;
margin-top: 40px;
align-items: center;
gap: 8px;
justify-content: start;
}
.section-activity .dots .dot {
border-radius: 8px;
background-color: rgba(157, 101, 198, 0.508);
align-self: stretch;
display: flex;
width: 12px;
height: 12px;
margin: auto 0;
transition: all 0.3s;
cursor: pointer;
}
.section-activity .dot.active {
width: 42px;
background-color: rgba(158, 101, 198, 1);
}
3. Javascript code
This JavaScript code initializes a carousel functionality for a group of activity cards. It handles the transition between different carousel items when navigation dots are clicked, and it also includes an optional auto-play feature that automatically advances the carousel every 5 seconds. The code ensures that the active dot and the corresponding carousel item are updated accordingly to provide a smooth user experience.
$(document).ready(function () {
const $activityGroup = $(".activity-group");
const $activityDots = $(".section-activity .dots .dot");
const totalActiveItems = $activityDots.length;
let currentActivityIndex = 0;
const activityGroupWidth = $activityGroup.eq(0).width();
function updateActivityCarousel() {
const offset = -currentActivityIndex * activityGroupWidth;
$activityGroup.css("transform", `translateX(${offset}px)`);
$activityDots.removeClass("active");
$activityDots.eq(currentActivityIndex).addClass("active");
}
$activityDots.on("click", function () {
currentActivityIndex = $(this).index();
updateActivityCarousel();
});
function nextActivitySlide() {
currentActivityIndex = (currentActivityIndex + 1) % totalActiveItems;
updateActivityCarousel();
}
// Auto-play functionality (optional)
setInterval(nextActivitySlide, 5000);
});