Open In App

Building a Carousel with Vanilla JavaScript

Last Updated : 23 Jul, 2025
Suggest changes
Share
11 Likes
Like
Report

A carousel, also known as an image slider, is a popular web component that allows users to cycle through a series of images, texts, or other content. we'll walk you through creating a responsive carousel using Vanilla JavaScript, HTML, and CSS without relying on any external libraries.

What We Are Going to Create

  • Basic Carousel: Use HTML to structure the images and CSS for layout and responsiveness.
  • Navigation Buttons: Add "Previous" and "Next" buttons to manually move through images.
  • Auto Play: Implement JavaScript to automatically cycle through images at intervals.
  • Styling: Use CSS to enhance the appearance with borders, shadows, transitions, and ensure responsiveness.

Project Preview

Carousel Application - HTML & CSS Structure

The first step in building a carousel is to define its HTML & CSS structure. We'll need a container for the carousel, individual images, and navigation buttons for the user to move between the images.

HTML
<html> <head> <style>  body {  font-family: Arial, sans-serif;  margin: 0;  padding: 0;  display: flex;  justify-content: center;  align-items: center;  height: 100vh;  background: #f4f4f4;  }  .car {  position: relative;  width: 80%;  max-width: 600px;  overflow: hidden;  }  .img-wrap {  display: flex;  transition: transform 0.5s ease;  }  .img-wrap img {  width: 100%;  height: auto;  }  .btn {  position: absolute;  top: 50%;  transform: translateY(-50%);  background: rgba(0, 0, 0, 0.5);  color: #fff;  border: none;  padding: 10px;  font-size: 16px;  cursor: pointer;  }  .btn:hover {  background: rgba(0, 0, 0, 0.8);  }  .prev {  left: 10px;  }  .next {  right: 10px;  }  </style> </head> <body> <div class="car"> <div class="img-wrap"> <img src="https://media.geeksforgeeks.org/wp-content/uploads/20241228102812942963/0_ilw552fVUGbwIzbE.jpg" alt="1"> <img src="https://media.geeksforgeeks.org/wp-content/uploads/20241128161121752603/what-is-javascript.webp" alt="2"> <img src="https://media.geeksforgeeks.org/wp-content/uploads/20240829155421/Amazing-new-Javascript-features-in-ES15.webp" alt="3"> </div> <button class="btn prev"></button> <button class="btn next"></button> </div> </body> </html> 

In this example

  • Body: Center content both vertically and horizontally, with a light background and no margin/padding.
  • Carousel: Restrict width to 80% with a max of 600px, and hide any overflow.
  • Image Wrapper: Arrange images in a row using flex, with smooth transition on transformation.
  • Images: Set images to take full width, keeping their aspect ratio intact.
  • Buttons: Position buttons (prev/next) in the center vertically, with semi-transparent background.
  • Button Hover: Darken button background on hover for better visibility.
  • Prev Button: Position the previous button to the left.
  • Next Button: Position the next button to the right.

Carousel - JavaScript Functionality

we add the functionality for navigating between images, as well as autoplay that switches the images automatically.

JavaScript
const prev = document.querySelector('.prev'); const next = document.querySelector('.next'); const wrap = document.querySelector('.img-wrap'); const imgs = document.querySelectorAll('.img-wrap img'); let idx = 0; function showImg() {  if (idx >= imgs.length) idx = 0;  if (idx < 0) idx = imgs.length - 1;  wrap.style.transform = `translateX(-${idx * 100}%)`; } next.addEventListener('click', () => {  idx++;  showImg(); }); prev.addEventListener('click', () => {  idx--;  showImg(); }); setInterval(() => {  idx++;  showImg(); }, 3000); showImg(); 

In this example

  • prev and next buttons for navigation are selected using querySelector.
  • wrap refers to the container for the images.
  • imgs holds all the individual images inside the wrap.
  • idx is a variable to keep track of the currently displayed image.
  • If idx is greater than or equal to the number of images, reset it to 0.
  • If idx is less than 0, reset it to the last image index.
  • Moves the wrap by updating its transform style to shift images horizontally based on the current idx.
  • Next Button: Increments idx and calls showImg() to display the next image.
  • Previous Button: Decrements idx and calls showImg() to display the previous image.
  • Uses setInterval to increment idx every 3000ms (3 seconds) and updates the displayed image via showImg().

Complete Code

HTML
<html> <head> <title>Vanilla JavaScript Carousel</title> <style>  body {  font-family: Arial, sans-serif;  margin: 0;  padding: 0;  display: flex;  justify-content: center;  align-items: center;  height: 100vh;  background: #f4f4f4;  }  .car {  position: relative;  width: 80%;  max-width: 600px;  overflow: hidden;  border-radius: 10px;  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);  }  .img-wrap {  display: flex;  transition: transform 0.5s ease;  }  .img-wrap img {  width: 100%;  height: auto;  flex-shrink: 0;  }  .btn {  position: absolute;  top: 50%;  transform: translateY(-50%);  background: rgba(0, 0, 0, 0.5);  color: #fff;  border: none;  padding: 10px;  font-size: 16px;  cursor: pointer;  border-radius: 50%;  }  .btn:hover {  background: rgba(0, 0, 0, 0.8);  }  .prev {  left: 10px;  }  .next {  right: 10px;  }  </style> </head> <body> <div class="car"> <div class="img-wrap"> <img src="https://media.geeksforgeeks.org/wp-content/uploads/20241228102812942963/0_ilw552fVUGbwIzbE.jpg" alt="Image 1"> <img src="https://media.geeksforgeeks.org/wp-content/uploads/20241128161121752603/what-is-javascript.webp" alt="Image 2"> <img src="https://media.geeksforgeeks.org/wp-content/uploads/20240829155421/Amazing-new-Javascript-features-in-ES15.webp" alt="Image 3"> </div> <button class="btn prev"></button> <button class="btn next"></button> </div> <script>  const prev = document.querySelector('.prev');  const next = document.querySelector('.next');  const wrap = document.querySelector('.img-wrap');  const imgs = document.querySelectorAll('.img-wrap img');  let idx = 0;  function showImg() {  if (idx >= imgs.length) idx = 0;  if (idx < 0) idx = imgs.length - 1;  wrap.style.transform = `translateX(-${idx * 100}%)`;  }  next.addEventListener('click', () => {  idx++;  showImg();  });  prev.addEventListener('click', () => {  idx--;  showImg();  });  setInterval(() => {  idx++;  showImg();  }, 3000);  showImg();  </script> </body> </html> 

Explore