A Vanilla JavaScript Slider

A Vanilla JavaScript slider in less than 30 lines.

by Ciprian Popescu

HTML

<script src="https://fonts.googleapis.com/css?family=Montserrat:400,700"></script>
<h2>A <a href="https://getbutterfly.com/how-to-build-a-vanilla-javascript-slider-in-less-than-100-lines/">Vanilla JavaScript Slider</a></h2>

<div class="slider">
  <div class="slide" data-background="https://evermotion.org/files/model_images/3e0dbe0ce65face2b9d44ab7f013762d499867ed.jpg"></div>
  <p class="caption caption-0">
    The first slide.
    <br><small>This is an awesome forest.</small>
  </p>
  <div class="slide" data-background="https://www.cbc.ca/natureofthings/content/images/episodes/talktalk_1920.jpg"></div>
  <p class="caption caption-1">
    The second slide, yay!
    <br><small>This is a marvellous forest.</small>
  </p>
  <div class="slide" data-background="https://cdn1.epicgames.com/ue/product/Screenshot/MAWIRedwoodForestPackV2Screenshot0001-1920x1080-e62973805ee13fbc3bca02a2ade9e9c4.jpg"></div>
  <p class="caption caption-2">
    Oh look, a third slide!
    <br><small>This is a bloody brilliant forest. It's CGI.</small>
  </p>
</div>

CSS

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
    font-size: 14px;
    font-weight: 300;
    line-height: 1.5;
    color: #24292e;
    background-color: #ffffff;
}

.slider {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 300px;
  margin: 48px auto;
  background-size: cover;
  border-radius: 3px;
  box-shadow: 0 0 16px rgba(0, 0, 0, 0.1);
  transition: background-image 0.8s ease-in-out;
}

.slider .slide {
  display: none;
}

.caption {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  opacity: 0;
  display: inline-block;
  padding: 48px;
  background: rgba(0, 0, 0, 0.75);
  color: white;
  margin: 0;
  font-size: 24px;
  font-weight: 500;
  transition: all 0.8s ease-in-out;
}

.caption small {
  font-size: 16px;
  font-weight: 300;
}

JavaScript

const slideArray = [];
for (let i = 0; i < document.querySelectorAll('.slider div').length; i++) {
  slideArray.push(document.querySelectorAll('.slider div')[i].dataset.background);
}

let currentSlideIndex = -1;

function advanceSliderItem() {
  currentSlideIndex++;

  if (currentSlideIndex >= slideArray.length) {
    currentSlideIndex = 0;
  }

  document.querySelector('.slider').style.cssText = 'background: url("' + slideArray[currentSlideIndex] + '") no-repeat center center; background-size: cover;';

  const elems = document.getElementsByClassName('caption');
  for (let i = 0; i < elems.length; i++) {
    elems[i].style.cssText = 'opacity: 0;';
  }

  const currentCaption = document.querySelector('.caption-' + (currentSlideIndex));
  currentCaption.style.cssText = 'opacity: 1;';
}

let intervalID = setInterval(advanceSliderItem, 3000);