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를 조작하면 미리보기와 코드가 실시간 갱신됩니다.

변형#

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타입기본값설명
itemsreadonly CarouselItem[]표시할 슬라이드 데이터 — key 안정성을 위해 children 대신 배열을 받는다
ariaLabelstring캐러셀 영역의 접근 가능한 이름 (필수)
variant'multiBrowse' | 'hero' | 'fullScreen'multiBrowse아이템 폭 레이아웃 (M3) — 기본 'multiBrowse'
previousLabelstring이전이전 버튼 aria-label (기본 '이전') — 현지화용 (Pagination 선례)
nextLabelstring다음다음 버튼 aria-label (기본 '다음') — 현지화용 (Pagination 선례)
controls'inline' | 'overlay'inline컨트롤 배치 — 'inline'(기본, 트랙 옆) · 'overlay'(슬라이드 위로 띄움). 'overlay'는 컨트롤에 중립 surface 계약 data-wds-surface="floating"을 부착해, liquid-glass 머티리얼 테마 스코프에서 clear 글래스(콘텐츠/미디어 위) 변형으로 칠해진다. compact 폭(<600px, ADR-012 BP.compact)에서는 띄우기를 끄고 inline 흐름으로 폴백해 컨트롤이 좁은 슬라이드의 미디어 가장자리를 가리지 않는다(아트디렉션 검수 H-2).
gapstring슬라이드 사이 간격 — 기본 토큰값. 과도한 매개변수화 금지
classNamestring루트에 병합
refRef<HTMLDivElement>루트 <div>로 전달되는 ref — 내부 trackRef와 별개 노드 (React 19 ref-as-prop)

접근성#

계약구현
영역루트 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 존중)