Project 4: Responsive Image Carousel
In this project, we will build a classic sliding image carousel. You will apply inline style translations, coordinate positions, click event handlers, and time loops (setInterval / clearInterval) to implement auto-rotation.
1. Project Features
- Manual navigation using Previous and Next buttons.
- Infinite looping: loops back to the start when reaching the end.
- Autoplay rotation every 3 seconds.
- Hover-to-Pause: Pauses rotation when hovering over the slider.
2. The HTML Structure
<!-- index.html -->
<div class="carousel-container" id="carousel">
<!-- Slides Track Wrapper -->
<div class="carousel-track" id="track">
<div class="slide"><img src="assets/slide1.jpg" alt="Slide 1"></div>
<div class="slide"><img src="assets/slide2.jpg" alt="Slide 2"></div>
<div class="slide"><img src="assets/slide3.jpg" alt="Slide 3"></div>
</div>
<!-- Navigation Buttons -->
<button class="nav-btn prev-btn" id="prev-btn">❮</button>
<button class="nav-btn next-btn" id="next-btn">❯</button>
<!-- Indicators / Dots -->
<div class="indicators" id="indicators">
<span class="dot active" data-slide="0"></span>
<span class="dot" data-slide="1"></span>
<span class="dot" data-slide="2"></span>
</div>
</div>3. The CSS Setup (Crucial for Layout)
The carousel container must hide overflow, and slides must sit horizontally in a row:
.carousel-container {
position: relative;
width: 600px;
height: 400px;
overflow: hidden; /* Hide slides off-screen */
border-radius: 12px;
}
.carousel-track {
display: flex;
width: 100%;
height: 100%;
transition: transform 0.5s ease-in-out; /* Smooth slide transition */
}
.slide {
min-width: 100%; /* Ensure each slide takes up full width of container */
height: 100%;
}
.slide img {
width: 100%;
height: 100%;
object-fit: cover;
}4. The JavaScript Implementation
// app.js
const track = document.querySelector('#track');
const slides = document.querySelectorAll('.slide');
const nextBtn = document.querySelector('#next-btn');
const prevBtn = document.querySelector('#prev-btn');
const indicatorsContainer = document.querySelector('#indicators');
const dots = document.querySelectorAll('.dot');
const carousel = document.querySelector('#carousel');
let currentIndex = 0;
let autoPlayInterval = null;
// 1. Move to a Specific Slide Index
function moveToSlide(index) {
// Infinite looping boundary checking
if (index >= slides.length) {
currentIndex = 0;
} else if (index < 0) {
currentIndex = slides.length - 1;
} else {
currentIndex = index;
}
// Calculate horizontal shift and apply transform translation
const amountToMove = -currentIndex * 100;
track.style.transform = `translateX(${amountToMove}%)`;
// Update indicator dots active state
updateDots();
}
// 2. Update Dots styling
function updateDots() {
dots.forEach((dot, index) => {
if (index === currentIndex) {
dot.classList.add('active');
} else {
dot.classList.remove('active');
}
});
}
// 3. Navigation Controls
nextBtn.addEventListener('click', () => {
moveToSlide(currentIndex + 1);
});
prevBtn.addEventListener('click', () => {
moveToSlide(currentIndex - 1);
});
// 4. Indicator Clicks using Event Delegation
indicatorsContainer.addEventListener('click', (e) => {
if (e.target.classList.contains('dot')) {
const targetIndex = parseInt(e.target.getAttribute('data-slide'));
moveToSlide(targetIndex);
}
});
// 5. Autoplay Loop Implementation
function startAutoplay() {
autoPlayInterval = setInterval(() => {
moveToSlide(currentIndex + 1);
}, 3000); // Shift every 3 seconds
}
function stopAutoplay() {
clearInterval(autoPlayInterval);
}
// 6. Pause on Hover
carousel.addEventListener('mouseenter', stopAutoplay);
carousel.addEventListener('mouseleave', startAutoplay);
// Initialize Carousel Autoplay on load
startAutoplay();5. Key Takeaways
translateX(%): Translating positions relative to element percentages is extremely clean and prevents having to query dynamic client widths (clientWidth).clearInterval: Always clean up running timers on hover (and during component destructions) to save CPU resources and prevent visual stuttering.
In the next module, we will recommend top books, playgrounds, and cheat sheets for Vanilla JS.
Published on Last updated: