<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);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.