<div class="page-wrap">

  <div class="slider">
    <div class="slider-inner">
      <!-- needs a minimum of 3 slides to work -->
      <figure class="slides">
        <img src="https://picsum.photos/970/340" alt="Slide1" width="970" height="340">
        <figcaption class="caption"><span>Slide 1</span></figcaption>
      </figure>
      <figure class="slides">
        <img src="https://picsum.photos/960/330" alt="Slide2" width="960" height="330">
        <figcaption class="caption"><span>Slide 2</span></figcaption>
      </figure>
      <figure class="slides">
        <img src="https://picsum.photos/990/350" alt="Slide3" width="990" height="350">
        <figcaption class="caption"><span>Slide 3</span></figcaption>
      </figure>
      <figure class="slides">
        <img src="https://picsum.photos/980/360" alt="Slide4" width="970" height="340">
        <figcaption class="caption"></span>Slide 4</span></figcaption>
      </figure>
      <!-- can use divs if preferred
      <div class="slides">Slide 5</div>
      <div class="slides">Slide 6</div>
      <div class="slides">Slide 7</div>
      <div class="slides">Slide 8</div>
      <div class="slides">Slide 9</div>
      <div class="slides">Slide 10</div>
-->
    </div>

  </div>
  <button id="previous" class="prev">Previous</button>
  <button id="next" class="next">Next</button>
  <!--  <button>stop autoplay</button>-->
  <p class="swipe">Swipe Images sideways to see Pictures</p>

</div>
/* the slider speed will be set in the js so this rule will be over-written*/
:root {
  --slider-speed: 0.5s;
}
html,
body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
}
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}
.page-wrap {
  max-width: 980px;
  margin: auto;
}
.slider {
  width: 100%;
  margin: 20px auto;
  position: relative;
  border: 5px inset #4c2c2c;
  background: #000;
  color: #fff;
  font-size: 2rem;
}
.slider-inner {
  /* Padding-top aspect ratio technique - adjust to suit images aspect ratio - this creates the height of the slides */
  padding-top: 35%;
  position: relative;
  overflow: hidden;
}
.slides {
  background: red;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  transform: translate3d(0, 0, 0);
}
.slides:first-child {
  z-index: 2;
}
.reverse .slides {
  transform: translate3d(-100%, 0, 0);
}
.forwards .slides {
  transform: translate3d(100%, 0, 0);
}
.slides.offLeft {
  transform: translate3d(-100%, 0, 0);
}
.slides.offRight {
  transform: translate3d(100%, 0, 0);
}

.slides.active {
  transform: translate3d(0%, 0, 0);
}
.slides.active,
.slides.offLeft,
.slides.offRight {
  transition: transform var(--slider-speed) linear;
  xtransition-duration: var(--slider-speed);
}

.slides:nth-child(odd) {
  background: blue;
}
.slides img {
  object-fit: cover;
  width: 100%;
  height: 100%;
  display: block;
}
.prev,
.next {
  margin: 5px 10px 5px 0;
  border: inset 5px solid #4c2c2c;
  padding: 5px 10px;
  background: #fefefe;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}
.prev:hover,
.next:hover,
.prev:focus,
.next:focus {
  background: #000;
  color: #fff;
  outline: 0;
}

.prev:not(.trans-end),
.next:not(.trans-end) {
  cursor: wait;
  opacity: 0.5;
}

/* captions if needed */
figure.slides {
  margin: 0;
  padding: 0;
}
.caption {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.caption span {
  padding: 20px;
  background: rgba(0, 0, 0, 0.5);
}

@media screen and (max-width: 1000px) {
  .page-wrap {
    margin: 0 10px;
  }
}

/* some touch styles*/
.swipe {
  display: none;
}
@media (hover: none) {
  .swipe {
    display: block;
  }
  .slider-inner {
    display: flex;
    padding-top: 0;
    height: 70vh;
    overflow-x: auto;
    overflow-y: hidden;
    -ms-scroll-snap-coordinate: 0 0;
    scroll-snap-coordinate: 0 0;
    -ms-scroll-snap-points-x: repeat(100%);
    scroll-snap-points-x: repeat(100%);
    -ms-scroll-snap-type: x mandatory;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
  }
  .slider-inner .slides {
    position: relative;
    flex: 1 0 100%;
    width: 100%;
    transform: none;
    scroll-snap-align: start;
  }
  #previous,
  #next {
    display: none;
  }
}
// Run function when page loads by putting JS at
// the end of the html before the closing body tag

const browserSupportsTouch =
  "ontouchstart" in window ||
  navigator.maxTouchPoints > 0 ||
  navigator.msMaxTouchPoints > 0;
if (browserSupportsTouch) {
  document.documentElement.className += " has-touch";
}

(function makeCarousel(d) {
  "use strict";

  if (browserSupportsTouch) {
    return;
  }

  const prev = d.querySelector("#previous");
  const next = d.querySelector("#next");
  const slides = d.querySelectorAll(".slides");
  const sliderInner = d.querySelector(".slider-inner");
  const time = 6000;
  const slide = {
    prev: 0,
    current: 0,
    next: 0,
    index: 0
  };

  // CSS custom variables
  const cssSliderSpeedProperty = "--slider-speed";
  const cssSliderSpeedValue = "0.5s";

  function setCssSliderSpeed() {
    document.documentElement.style.setProperty(
      cssSliderSpeedProperty,
      cssSliderSpeedValue
    );
  }

  function init() {
    setCssSliderSpeed();

    slides[0].classList.add("active");
    sliderInner.classList.add("forwards");
    // detect if transitioning or not
    prev.classList.add("trans-end");
    next.classList.add("trans-end");
    // offset left is so slides can go either way
    slides[slides.length - 1].classList.add("offLeft");
  }

  function checkTransition() {
    const inTransit = d.querySelector(".slides.active");
    inTransit.ontransitionend = function endTransition() {
      console.log("Transition ended");
      next.classList.add("trans-end");
      prev.classList.add("trans-end");
    };
  }

  function initSlides(added, removed) {
    // check if moving before moving again
    checkTransition();

    sliderInner.classList.remove(removed);
    sliderInner.classList.add(added);

    if (slide.index === slides.length) {
      slide.index = 0;
    }
    if (slide.index === -1) {
      slide.index = slides.length - 1;
    }

    console.log(slide.index);
    slide.current = slide.index;
    slide.prev = slide.index - 1;
    slide.next = slide.index + 1;

    if (slide.index === 0) {
      slide.prev = slides.length - 1;
      slide.next = slide.index + 1;
    }
    if (slide.index === slides.length - 1) {
      slide.prev = slide.index - 1;
      slide.next = 0;
    }
  }

  function changeImage() {
    if (sliderInner.classList.contains("forwards")) {
      next.click();
    } else {
      prev.click();
    }
    setTimeout(changeImage, time);
  }

  function nextSlide() {
    if (next.classList.contains("trans-end")) {
      initSlides("forwards", "reverse");

      slides[slide.current].classList.add("offLeft");
      slides[slide.current].classList.remove("active");
      slides[slide.prev].classList.remove("offLeft");
      slides[slide.next].classList.add("active");
      slides[slide.next].classList.remove("offRight");
      slide.index += 1;
      next.classList.remove("trans-end");
    }
  }

  function prevSlide() {
    if (prev.classList.contains("trans-end")) {
      initSlides("reverse", "forwards");

      slides[slide.current].classList.add("offRight");
      slides[slide.current].classList.remove("active");
      slides[slide.next].classList.remove("offRight");
      slides[slide.prev].classList.add("active");
      slides[slide.prev].classList.remove("offLeft");

      slide.index -= 1;
      prev.classList.remove("trans-end");
    }
  }

  init();
  changeImage();

  next.addEventListener("click", nextSlide);
  prev.addEventListener("click", prevSlide);
})(document);
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.