ComponentsP3 본문

Carousel

가로 스크롤 캐러셀 — scroll-snap 트랙 + 이전/다음 컨트롤, multiBrowse·hero·fullScreen 레이아웃(ADR-012 Track C).

마지막 업데이트 2026-06-12

한눈에#

scroll-snap 트랙 + 이전/다음 컨트롤로 항목을 가로로 훑는 캐러셀입니다 — multiBrowse·hero·fullScreen 레이아웃을 제공합니다.

  • scroll-snap 가로 트랙
  • multiBrowse·hero·fullScreen
  • 이전/다음 컨트롤
  • overlay 글래스 컨트롤

items는 { id, content } 배열 — 트랙은 항목 경계에 스냅되고 버튼이 한 항목씩 스크롤

items{ id, content } 배열입니다 — id가 안정적인 key가 됩니다. 트랙은 scroll-snap으로 항목 경계에 맞춰지고, 이전/다음 버튼이 한 항목씩 스크롤합니다.

사용 시점#

추천 항목·미디어·배너를 가로로 훑는 컬렉션이면 Carousel — 동등 패널을 한 번에 하나씩 보는 건 다른 컴포넌트입니다.

쓴다

추천 항목·미디어 갤러리·배너처럼 가로로 스크롤하며 훑는 컬렉션

대신 Tabs

동등한 콘텐츠 패널을 한 번에 하나씩 전환할 때

플레이그라운드#

컨트롤로 props를 조작하면 미리보기와 코드가 실시간 갱신됩니다.

import { Carousel } from '@wds/ui-web';

<Carousel ariaLabel="추천 항목" items={[{ id: 'a', content: '카드 A' }, /* … */]} />

변형#

variant가 항목 너비(레이아웃)를 가릅니다 — multiBrowse(기본, 여러 항목)·hero(큰 포컬 항목 + 다음 항목 살짝)·fullScreen(한 화면 한 항목).

hero — 포컬 항목 + 다음 항목 peek

오버레이 컨트롤#

controls="overlay"는 이전/다음 버튼을 슬라이드 위로 띄웁니다 — 미디어·이미지 위에 컨트롤이 떠 있는 패턴입니다. 컨트롤엔 중립 surface 계약 data-wds-surface="floating"이 붙어, liquid-glass 머티리얼 테마 스코프 안에서는 clear 글래스(콘텐츠 위 변형)로 칠해집니다 — 기본 테마에선 일반 불투명 버튼입니다. 아래 데모는 data-wds-material="liquid-glass"로 감싸 glass 컨트롤을 보여줍니다.

overlay — 슬라이드 위로 띄운 컨트롤 (liquid-glass → clear 글래스)

prefers-reduced-transparency에서는 테마 레이어가 자동으로 불투명 surface로 폴백하고 blur를 제거합니다 — 컨트롤 가독성이 우선됩니다.

compact 폭(<600px, ADR-012 적응형 경계 BP.compact)에서는 띄우기를 자동으로 꺼서 컨트롤을 트랙 옆 inline 흐름으로 폴백합니다 — 좁은 화면에서 40px 컨트롤 2개가 슬라이드의 약 1/3을 가려 미디어 가장자리를 잠식하지 않도록 합니다. 태블릿·데스크톱(≥600px, overlay의 의도된 미디어 갤러리 용처)에서만 슬라이드 위로 띄웁니다.

크기#

레이아웃이 variant로 정해지므로 별도 size 축은 없습니다 — 항목 너비는 트랙 폭에 대한 비율로 결정됩니다. 트랙 폭은 부모 컨테이너가 정합니다.

상태#

스크롤 위치에 따라 이전/다음 버튼이 자동으로 비활성화됩니다 — 시작에서는 이전이, 끝에서는 다음이 disabled. 모션은 prefers-reduced-motion을 존중해 허용될 때만 부드럽게 스크롤합니다.

Props#

Prop타입기본값설명
itemsReadonlyArray<{ id: string; content: ReactNode }>슬라이드 배열 — id가 안정적 key
variant'multiBrowse' | 'hero' | 'fullScreen''multiBrowse'레이아웃 — 항목 너비를 결정
ariaLabelstring캐러셀 영역의 접근성 이름 — 필수
previousLabelstring'이전'이전 버튼 aria-label — 현지화용
nextLabelstring'다음'다음 버튼 aria-label — 현지화용
controls'inline' | 'overlay''inline'컨트롤 배치 — 'overlay'는 슬라이드 위로 띄우고 data-wds-surface='floating' 계약을 부착(liquid-glass에서 clear 글래스)
gapstring항목 간격 — 기본은 토큰 간격
classNamestring루트에 병합

접근성#

계약구현
영역루트 role="group" + aria-roledescription="carousel" + aria-label(=ariaLabel)
슬라이드각 항목 role="group" + aria-roledescription="slide" + aria-label="N / total"
컨트롤이전/다음 <button> aria-label(기본 "이전"/"다음", previousLabel·nextLabel로 현지화), 경계에서 disabled
키보드트랙 포커스(tabindex=0) + ArrowLeft/ArrowRight 스크롤
모션scroll-behavior: smoothprefers-reduced-motion: no-preference에서만

토큰#

component 토큰 없이 semantic을 직접 소비합니다(신설 기준 §4 미충족).

속성토큰
컨트롤 버튼color.surface · shadow.sm · radius.full · hover color.surface-hover → 눌림 color.surface-pressed(:focus-visible 2px color.focus-ring)
간격space.* 토큰
모션duration.normal + ease.standard (reduced-motion 존중)