A super tiny, easy-to-use, and infinitely looping image carousel slider created using plain JavaScript and CSS.
1. Add carousel items (images) to the webpage.
<div class="carousel-wrapper">
<div class="carousel">
<button id="carouselPreviousSlideButton" class="carousel__button carousel__button--left">
<img src="./images/carousel-arrow-left.svg" alt="">
</button>
<div class="carousel__track-container">
<ul id="track" class="carousel__track">
<li class="carousel__slide current-slide">
<img class="carousel__image" src="./images/hunter-exam-arc-img.jpg" alt="">
</li>
<li class="carousel__slide">
<img class="carousel__image" src="./images/phantom-troupe-arc-img.jpg" alt="">
</li>
<li class="carousel__slide">
<img class="carousel__image" src="./images/gon-intense-bloodlust.jpg" alt="">
</li>
<li class="carousel__slide">
<img class="carousel__image" src="./images/netero-heart-pose.jpg" alt="">
</li>
<li class="carousel__slide">
<img class="carousel__image" src="./images/killua-godspeed-invoked.jpg" alt="">
</li>
</ul>
</div>
<button id="carouselNextSlideButton" class="carousel__button carousel__button--right">
<img src="./images/carousel-arrow-right.svg" alt="">
</button>
<div id="carouselNav" class="carousel__nav">
<button class="carousel__indicator current-slide"></button>
<button class="carousel__indicator"></button>
<button class="carousel__indicator"></button>
<button class="carousel__indicator"></button>
<button class="carousel__indicator"></button>
</div>
</div>
</div>
2. The core CSS styles for the carousel.
.carouse-wrapper {
max-height: 501px;
}
.carousel {
height: 501px;
margin: 0 auto;
position: relative;
max-width: 751px;
}
.carousel__image {
height: 100%;
object-fit: cover;
width: 100%;
}
.carousel__track-container {
background-color: gray;
height: 100%;
position: relative;
overflow: hidden;
}
.carousel__track {
list-style: none;
margin: 0;
padding: 0;
position: relative;
height: 100%;
transition: transform 400ms ease;
}
.carousel__slide {
bottom: 0;
position: absolute;
top: 0;
width: 100%;
}
3. The necessary CSS styles for the carousel controls.
.carousel__button {
cursor: pointer;
top: 50%;
transform: translateY(-50%);
position: absolute;
background-color: rgba(255, 255, 255, 0.75);
border: unset;
padding: 0;
z-index: 100;
border-radius: 50%;
padding: 7px;
outline: none;
}
.carousel__button--right {
right: 10px;
}
.carousel__button--left {
left: 10px;
}
.carousel__button img {
width: 20px;
height: 20px;
display: block;
}
.carousel__nav {
display: flex;
justify-content: center;
margin-top: 16px;
}
.carousel__indicator {
border: unset;
border-radius: 50%;
cursor: pointer;
width: 10px;
height: 10px;
background-color: rgb(182, 182, 182, 0.7);
padding: 0;
margin: 0 5px;
outline: none;
}
.carousel__indicator.current-slide {
background-color: rgba(0, 0, 0, 0.7);
}
4. Enable the carousel by adding the following JavaScript snippets to the page.
const track = document.getElementById('track'),
slides = Array.from(track.children),
nextSlideButton = document.getElementById('carouselNextSlideButton'),
previousSlideButton = document.getElementById('carouselPreviousSlideButton'),
carouselNav = document.getElementById('carouselNav'),
carouselNavDots = Array.from(carouselNav.children);
window.addEventListener('resize', setSlideImagePosition)
// position slide images parallel to one another horizontally
function setSlideImagePosition() {
slideXDimension = slides[0].getBoundingClientRect().width;
for (let index = 0; index < slides.length; index++) {
slides[index].style.left = `${index * slideXDimension}px`
}
const currentSlide = track.querySelector('.current-slide');
track.style.transform = `translateX(-${currentSlide.style.left})`
}
setSlideImagePosition();
// current slide is moved to the left when next button is clicked
function moveSlide(track, currentSlide, targetSlide) {
track.style.transform = `translateX(-${targetSlide.style.left})`;
currentSlide.classList.remove('current-slide');
targetSlide.classList.add('current-slide');
}
nextSlideButton.addEventListener('click', function () {
const currentSlide = track.querySelector('.current-slide');
const targetSlide = currentSlide.nextElementSibling;
const currentDot = carouselNav.querySelector('.current-slide');
const nextDot = currentDot.nextElementSibling;
if (targetSlide) {
moveSlide(track, currentSlide, targetSlide)
updateCarouselDots(currentDot, nextDot)
} else {
const targetSlide = slides[0];
const nextDot = carouselNavDots[0]
moveSlide(track, currentSlide, targetSlide)
updateCarouselDots(currentDot, nextDot)
}
})
previousSlideButton.addEventListener('click', function () {
const currentSlide = track.querySelector('.current-slide');
const targetSlide = currentSlide.previousElementSibling;
const currentDot = carouselNav.querySelector('.current-slide');
const nextDot = currentDot.previousElementSibling;
if (targetSlide) {
moveSlide(track, currentSlide, targetSlide)
updateCarouselDots(currentDot, nextDot)
} else {
const targetSlide = slides[slides.length - 1];
const nextDot = carouselNavDots[carouselNavDots.length - 1]
moveSlide(track, currentSlide, targetSlide)
updateCarouselDots(currentDot, nextDot)
}
})
carouselNav.addEventListener('click', function (event) {
targetDot = event.target.closest('button');
console.log(targetDot)
if (!targetDot) {
return
}
const currentSlide = track.querySelector('.current-slide'),
currentDot = carouselNav.querySelector('.current-slide'),
targetIndex = carouselNavDots.findIndex(dot => dot === targetDot),
targetSlide = slides[targetIndex];
moveSlide(track, currentSlide, targetSlide);
updateCarouselDots(currentDot, targetDot);
})
function updateCarouselDots(currentDot, targetDot) {
currentDot.classList.remove('current-slide');
targetDot.classList.add('current-slide');
}
slides.forEach(setSlideImagePosition)
Author: judzelicor
Demo: https://judzelicor.github.io/simple-infinite-carousel/
Source Code: https://github.com/judzelicor/simple-infinite-carousel
#javascript