javascript 51 lines · 9 steps

Building an accessible auto-playing carousel

A self-contained Carousel class that cycles slides on a timer while respecting hover, tab visibility, and screen readers.

Explained by highlit
1class Carousel {
2 constructor(root, { interval = 5000 } = {}) {
3 this.root = root;
4 this.track = root.querySelector('.carousel__track');
5 this.slides = Array.from(root.querySelectorAll('.carousel__slide'));
6 this.dots = Array.from(root.querySelectorAll('.carousel__dot'));
7 this.interval = interval;
8 this.index = 0;
9 this.timer = null;
10 
11 this.root.addEventListener('mouseenter', () => this.pause());
12 this.root.addEventListener('mouseleave', () => this.play());
13 this.dots.forEach((dot, i) => dot.addEventListener('click', () => this.goTo(i)));
14 document.addEventListener('visibilitychange', () =>
15 document.hidden ? this.pause() : this.play()
16 );
17 
18 this.render();
19 this.play();
20 }
21 
22 render() {
23 this.track.style.transform = `translateX(-${this.index * 100}%)`;
24 this.slides.forEach((slide, i) =>
25 slide.setAttribute('aria-hidden', String(i !== this.index))
26 );
27 this.dots.forEach((dot, i) =>
28 dot.classList.toggle('is-active', i === this.index)
29 );
30 }
31 
32 goTo(index) {
33 this.index = (index + this.slides.length) % this.slides.length;
34 this.render();
35 this.play();
36 }
37 
38 next() {
39 this.goTo(this.index + 1);
40 }
41 
42 play() {
43 this.pause();
44 this.timer = setInterval(() => this.next(), this.interval);
45 }
46 
47 pause() {
48 clearInterval(this.timer);
49 this.timer = null;
50 }
51}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Storing a single index and re-deriving the DOM from it keeps UI state predictable.
  2. 2Pausing timers on hover and tab-hidden avoids wasted work and jarring jumps.
  3. 3Toggling aria-hidden alongside visual state keeps assistive tech in sync with what's shown.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Building an accessible auto-playing carousel — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code