<section class="slider">
  <!-- radio buttons start -->
  <input type="radio" name="radio-btn" id="radio1" checked />
  <input type="radio" name="radio-btn" id="radio2" />
  <input type="radio" name="radio-btn" id="radio3" />
  <input type="radio" name="radio-btn" id="radio4" />
  <!-- radio buttons end -->
  <!-- slides start -->
  <ul class="slides-flex">
    <li class="slide">
      <h2>1</h2>
    </li>
    <li class="slide">
      <h2>2</h2>
    </li>
    <li class="slide">
      <h2>3</h2>
    </li>
    <li class="slide">
      <h2>4</h2>
    </li>
  </ul>
  <!-- slides end -->
  <!-- navigation start -->
  <div class="navigation">
    <label for="radio1" class="btn1" id="1"></label>
    <label for="radio2" class="btn2" id="2"></label>
    <label for="radio3" class="btn3" id="3"></label>
    <label for="radio4" class="btn4" id="4"></label>
  </div>
  <!-- navigation end -->
</section>
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300&display=swap");

*,
*::before,
*::after {
  padding: 0;
  margin: 0;
}

:root {
  --primaryColor: #333;
}

body {
  display: grid;
  height: 100vh;
  place-items: center;
  background-color: rgb(208, 230, 249);
  font-family: "Poppins", sans-serif;
}

ul {
  list-style: none;
}

.slider {
  position: relative;
  width: 80%;
  aspect-ratio: 1;
  max-width: 50rem;
  max-height: 31.25rem;
  border-radius: 0.7rem;
  overflow: hidden;
  cursor: grab;
}

.slider input {
  display: none;
}

/* SLIDES */
.slides-flex {
  position: absolute;
  left: 0;
  width: 400%;
  height: 100%;
  display: flex;
  transition: 0.8s;
}

.slide {
  width: 25%;
  display: grid;
  place-items: center;
}

.slide:nth-child(1) {
  background-color: #fed050;
  border-radius: 0.7rem 0 0 0.7rem;
}

.slide:nth-child(2) {
  background-color: #7fdbee;
}

.slide:nth-child(3) {
  background-color: #4cf89c;
}

.slide:nth-child(4) {
  background-color: #f79191;
  border-radius: 0 0.7rem 0.7rem 0;
}

.slide h2 {
  user-select: none;
  color: var(--primaryColor);
  height: 5rem;
  width: 5rem;
  font-size: 3rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  text-align: center;
  outline: 3px solid;
}

/* NAVIGATION */
.navigation {
  position: absolute;
  user-select: none;
  width: 100%;
  bottom: 2.5rem;
  display: flex;
  gap: 2rem;
  justify-content: center;
}

.navigation label {
  border: 2px solid var(--primaryColor);
  padding: 0.3rem;
  border-radius: 50%;
  cursor: pointer;
  transition: 1s;
}

/* ON RADIO CHECKED */
/* #radio1:checked ~ .slides-flex {
  left: 0%;
}

#radio2:checked ~ .slides-flex {
  left: -100%;
}

#radio3:checked ~ .slides-flex {
  left: -200%;
}

#radio4:checked ~ .slides-flex {
  left: -300%;
} */

#radio1:checked ~ .navigation .btn1 {
  background: var(--primaryColor);
}

#radio2:checked ~ .navigation .btn2 {
  background: var(--primaryColor);
}

#radio3:checked ~ .navigation .btn3 {
  background: var(--primaryColor);
}

#radio4:checked ~ .navigation .btn4 {
  background: var(--primaryColor);
}
const slideContainer = document.querySelector(".slider");
const slidesFlex = document.querySelector(".slides-flex");
const navigation = document.querySelector(".navigation");

(function slider(container, slidesFlex, navigation) {
  let initialX,
    finalX,
    leftPos = -100,
    clicked = false,
    counter = 0,
    slideDistance,
    interval = null,
    numberOfSlides = slidesFlex.childElementCount,
    slidesWidth = slidesFlex.offsetWidth,
    threshold = 40;

  // *******EVENT LISTENERS******
  // initiate interval
  document.addEventListener("DOMContentLoaded", createInterval);

  // mouse events
  container.addEventListener("mousedown", dragStart);

  // touch events
  container.addEventListener("touchstart", dragStart);
  container.addEventListener("touchmove", dragging);
  container.addEventListener("touchend", dragStop);

  // ******FUNCTIONS******
  function moveSlide() {
    slidesFlex.style.left = `${leftPos * counter}%`;
    document.getElementById("radio" + (counter + 1)).checked = true;
  }

  function animate() {
    if (clicked) return; //stop if dragging
    counter++;
    if (counter > numberOfSlides - 1) {
      counter = 0;
      slidesFlex.style.transition = "none";
    } else {
      slidesFlex.style.transition = "0.8s";
    }
    moveSlide();
  }

  function createInterval() {
    if (!interval) {
      interval = setInterval(animate, 5000);
    }
  }

  function dragStart(e) {
    clearInterval(interval);
    interval = null;

    // handling manual navigation
    if (navigation.contains(e.target)) {
      counter = e.target.id ? parseInt(e.target.id) - 1 : counter;
      slidesFlex.style.transition = "0.8s";
      moveSlide();
      createInterval();
      return;
    }
    e.preventDefault(); // for touchscreen defaults

    // sliding animation
    slidesFlex.style.transition = "0.5s";
    container.style.cursor = "grabbing";
    document.body.style.cursor = "grabbing";

    clicked = true;

    if (e.type == "touchstart") {
      initialX = e.touches[0].clientX;
    } else {
      initialX = e.clientX;
      document.onmousemove = dragging;
      document.onmouseup = dragStop;
    }
  }

  function dragging(e) {
    if (!clicked) return;

    if (e.type == "touchmove") {
      finalX = e.touches[0].clientX;
    } else {
      finalX = e.clientX;
    }

    let currentPosition = counter * leftPos;

    slideDistance =
      ((initialX - finalX) / (slidesWidth / numberOfSlides)) * 100;

    if (Math.abs(slideDistance) < threshold) {
      slidesFlex.style.left = `${currentPosition - slideDistance}%`;
    }
  }

  function dragStop(e) {
    if (navigation.contains(e.target)) return;

    // check threshold and counter before changing slides
    if (finalX < initialX && counter < numberOfSlides - 1 && slideDistance >= threshold) {
      counter++;
    } else if (
      finalX > initialX &&
      counter > 0 &&
      -slideDistance >= threshold
    ) {
      counter--;
    }
    moveSlide();

    // return to default
    createInterval();
    document.body.style.cursor = "default";
    container.style.cursor = "grab";
    initialX = undefined;
    finalX = undefined;
    clicked = false;
    document.onmousemove = null;
    document.onmouseup = null;
  }
})(slideContainer, slidesFlex, navigation);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.