Pure JS & CSS Carousel

Author avatar

QUOC HUY NGUYEN

· 5 min read
Pure JS & CSS Carousel

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);
});
QUOC HUY NGUYEN

About QUOC HUY NGUYEN

Time is free, but it’s priceless. You can’t own it, but you can use it. You can’t keep it, but you can spend it. Once you’ve lost it you can never get it back