캐러셀

Carousel

여러 장의 콘텐츠를 하나씩 옆으로 넘기며 순환해서 보여주는 슬라이드 묶음.

다른 이름: SlideshowImage carousel
···
html
<div class="car">
  <div class="track" id="ctrk">
    <div class="slide" style="background:linear-gradient(135deg,#5b5bf7,#8a7bff)" aria-roledescription="slide">봄 컬렉션</div>
    <div class="slide" style="background:linear-gradient(135deg,#f25c8a,#ff9b7a)" aria-roledescription="slide">여름 세일</div>
    <div class="slide" style="background:linear-gradient(135deg,#18c29c,#5be3c9)" aria-roledescription="slide">가을 신상</div>
  </div>
  <button class="carpause" id="cpz" aria-pressed="false">⏸</button>
  <div class="dots" id="cdots"><button aria-current="true"></button><button></button><button></button></div>
</div>
css
.car{position:relative;width:100%;height:100%;overflow:hidden}
.track{display:flex;width:300%;height:100%;transition:transform .5s ease}
.slide{width:calc(100%/3);display:grid;place-items:center;color:#fff;font-weight:800;font-size:18px}
.carpause{position:absolute;top:8px;right:8px;width:26px;height:26px;border-radius:50%;border:0;background:rgba(0,0,0,.35);color:#fff;font-size:11px;cursor:pointer}
.dots{position:absolute;bottom:10px;left:50%;transform:translateX(-50%);display:flex;gap:6px}
.dots button{width:6px;height:6px;border-radius:50%;border:0;background:rgba(255,255,255,.5);cursor:pointer;padding:0}
.dots button[aria-current]{background:#fff;width:16px;border-radius:3px}
js
const trk = document.getElementById('ctrk'), dots = [...document.querySelectorAll('.dots button')], pz = document.getElementById('cpz');
let i = 0, playing = true;
function go(n) { i = (n + 3) % 3; trk.style.transform = 'translateX(-' + (i * 100 / 3) + '%)'; dots.forEach((d, idx) => idx === i ? d.setAttribute('aria-current', 'true') : d.removeAttribute('aria-current')); }
dots.forEach((d, idx) => d.addEventListener('click', () => go(idx)));
pz.addEventListener('click', () => { playing = !playing; pz.setAttribute('aria-pressed', String(!playing)); pz.textContent = playing ? '⏸' : '▶'; });
setInterval(() => { if (playing) go(i + 1); }, 2400);

각 슬라이드에 aria-roledescription="slide"를, 전체 컨테이너에 aria-live="polite" 또는 사용자가 넘길 때만 알리는 처리를 둡니다. 자동재생을 켰다면 WCAG 2.2.2 요구사항에 따라 일시정지 버튼을 반드시 제공해야 합니다 — 자동으로 움직이는 콘텐츠는 저시력·인지장애 사용자에게 읽을 시간을 빼앗습니다.

페이지네이션과 다른 점은 위에서 다룬 대로 "탐색 대상"의 성격입니다 — 페이지네이션은 목록 데이터를 구간별로 나눠 탐색하고, 캐러셀은 이미지나 프로모션 카드 같은 콘텐츠 자체를 슬라이드로 순환 전시합니다. 값을 고르는 range 슬라이더와는 이름만 겹칠 뿐 전혀 다른 컴포넌트입니다.

화살표·도트 버튼에는 "다음 슬라이드", "2번 슬라이드로 이동" 같은 명확한 라벨을 달아야 합니다.