Welcome to this tutorial on Creating a Responsive Image Slider. Carousels and sliders are a staple of modern web design, perfect for showcasing portfolios, hero images, or product galleries.

Instead of relying on heavy plugins like Slick or Swiper, we will build a lightweight, auto-playing slider from scratch using Vanilla JavaScript.

1. The HTML Layout

We need a main .slider-container. Inside, we place our .slide elements (which hold the image and text), our navigation arrows (<button>), and our pagination dots.

<div class="slider-container">
  
  <div class="slide active">
    <img src="mountains.jpg" alt="Nature">
    <div class="slide-content">
      <h2>Majestic Mountains</h2>
      <p>Explore the beauty of the high peaks.</p>
    </div>
  </div>
  
  <div class="slide">
    <img src="forest.jpg" alt="Forest">
    <!-- ... -->
  </div>

  <!-- Navigation Arrows -->
  <button class="arrow prev" onclick="moveSlide(-1)">❮</button>
  <button class="arrow next" onclick="moveSlide(1)">❯</button>

  <!-- Dots -->
  <div class="dots">
    <div class="dot active" onclick="currentSlide(0)"></div>
    <div class="dot" onclick="currentSlide(1)"></div>
  </div>
  
</div>

2. CSS Positioning and Animations

We stack all the .slide elements on top of each other using position: absolute. We hide them all using opacity: 0, and only show the one with the .active class.

.slider-container {
  position: relative;
  width: 100%;
  max-width: 800px;
  height: 450px;
  overflow: hidden;
}

.slide {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  opacity: 0; /* Hidden by default */
  transition: opacity 0.5s ease-in-out;
}

.slide.active {
  opacity: 1; /* Visible when active */
  z-index: 1;
}

/* Animate text sliding up when slide becomes active */
.slide-content {
  transform: translateY(20px);
  opacity: 0;
  transition: all 0.5s ease 0.3s;
}

.slide.active .slide-content {
  transform: translateY(0);
  opacity: 1;
}

3. The JavaScript Logic

Our JavaScript needs to do three things:

  1. Keep track of the current slideIndex.
  2. Update the .active classes when arrows or dots are clicked.
  3. Automatically advance the slide every 5 seconds.
let slideIndex = 0;
const slides = document.querySelectorAll('.slide');
const dots = document.querySelectorAll('.dot');
let timer;

// Main function to display a specific slide
function showSlide(n) {
  // Loop back to start if we go past the last slide
  if (n >= slides.length) slideIndex = 0;
  // Loop to the end if we go backwards from the first slide
  if (n < 0) slideIndex = slides.length - 1;

  // Remove 'active' class from ALL slides and dots
  slides.forEach(slide => slide.classList.remove('active'));
  dots.forEach(dot => dot.classList.remove('active'));

  // Add 'active' class to the CURRENT slide and dot
  slides[slideIndex].classList.add('active');
  dots[slideIndex].classList.add('active');
}

// Called by the Prev/Next arrows
function moveSlide(n) {
  slideIndex += n;
  showSlide(slideIndex);
  resetTimer(); // Reset auto-play so it doesn't instantly change again
}

// Called by the Navigation Dots
function currentSlide(n) {
  slideIndex = n;
  showSlide(slideIndex);
  resetTimer();
}

Implementing Auto-Play

We use setInterval to call moveSlide(1) every 5000 milliseconds.

function autoPlay() {
  slideIndex++;
  showSlide(slideIndex);
}

function resetTimer() {
  clearInterval(timer);
  timer = setInterval(autoPlay, 5000);
}

// Start auto-play on page load
resetTimer();

And there you have it! A fully functional, responsive, auto-playing image slider without writing a single line of jQuery. Check out the Live Demo to see the smooth cross-fade animations!