메인 콘텐츠로 건너뛰기

캐러셀 구성요소

마지막 업데이트:

스크롤-스냅을 사용하는 CSS 전용 Tailwind CSS 캐러셀. 탐색 컨트롤이 있고 JavaScript가 필요하지 않은 가로 슬라이드 레이아웃입니다. WCAG AA 액세스 가능하며 Django, HTMX, Laravel, React 및 모든 스택에서 작동합니다.

캐러셀 구성 요소는 회전 또는 스크롤 가능한 컨테이너에 여러 항목을 표시하므로 이미지, 사용후기, 제품 갤러리 또는 추천 콘텐츠를 표시하는 데 적합합니다. 시맨틱 HTML과 부드러운 스크롤 동작으로 구축된 캐러셀은 스냅 정렬을 통해 수평 및 수직 레이아웃을 지원합니다. Frutjam 캐러셀 시스템은 히어로 섹션, 제품 갤러리, 추천 표시 및 콘텐츠 슬라이더에 적합합니다.

CSS 전용이며 JavaScript가 필요하지 않습니다. WCAG AA 액세스 가능 및 프레임워크에 구애받지 않음 — Django, HTMX, Laravel, React 및 모든 스택에서 작동합니다.

수업 유형 설명
carousel베이스스냅 동작이 있는 가로 스크롤 가능 컨테이너
carousel-item수정자캐러셀 내부의 개별 슬라이드
carousel-vertical수정자세로 스크롤 방향
carousel-center수정자각 항목의 중앙에 맞춤 맞춤
carousel-end수정자각 항목의 끝 부분에 맞춤 맞춤

기본 사용법

스크롤 가능한 항목이 포함된 간단한 수평 캐러셀을 만듭니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<div class="carousel w-full gap-4 p-4 bg-base-100">
  <div class="carousel-item w-96">
    <div class="badge badge-primary">Featured</div>
  </div>
  <div class="carousel-item w-96">
    <div class="badge badge-secondary">Popular</div>
  </div>
  <div class="carousel-item w-96">
    <div class="badge badge-accent">Trending</div>
  </div>
  <div class="carousel-item w-96">
    <div class="badge badge-info">New</div>
  </div>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<div className="carousel w-full gap-4 p-4 bg-base-100">
  <div className="carousel-item w-96">
    <div className="badge badge-primary">Featured</div>
  </div>
  <div className="carousel-item w-96">
    <div className="badge badge-secondary">Popular</div>
  </div>
  <div className="carousel-item w-96">
    <div className="badge badge-accent">Trending</div>
  </div>
  <div className="carousel-item w-96">
    <div className="badge badge-info">New</div>
  </div>
</div>

부드러운 스크롤과 반응형 크기 조정으로 이미지 갤러리를 표시합니다.

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<div class="carousel w-full gap-2">
  <div class="carousel-item w-full">
    <picture>
      <source media="(max-width: 640px)" srcset="https://cdn.frutjam.com/images/photo-2.jpg?format=webp&width=640&height=360">
      <img src="https://cdn.frutjam.com/images/photo-2.jpg?format=webp&width=800&height=450" alt="Image 1" class="w-full" loading="lazy" />
    </picture>
  </div>
  <div class="carousel-item w-full">
    <picture>
      <source media="(max-width: 640px)" srcset="https://cdn.frutjam.com/images/photo-3.jpg?format=webp&width=640&height=360">
      <img src="https://cdn.frutjam.com/images/photo-3.jpg?format=webp&width=800&height=450" alt="Image 2" class="w-full" loading="lazy" />
    </picture>
  </div>
  <div class="carousel-item w-full">
    <picture>
      <source media="(max-width: 640px)" srcset="https://cdn.frutjam.com/images/photo-4.jpg?format=webp&width=640&height=360">
      <img src="https://cdn.frutjam.com/images/photo-4.jpg?format=webp&width=800&height=450" alt="Image 3" class="w-full" loading="lazy" />
    </picture>
  </div>
</div>

중앙 스냅 정렬 및 카드 간 간격을 사용하여 회전식 항목을 표시합니다.

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="carousel carousel-center gap-4 p-4 bg-base-200 rounded-lg">
  <div class="carousel-item">
    <div class="card card-primary w-80">
      <div class="card-content">
        <h2 class="card-title">Card 1</h2>
        <p>Featured product or content</p>
      </div>
    </div>
  </div>
  <div class="carousel-item">
    <div class="card card-secondary w-80">
      <div class="card-content">
        <h2 class="card-title">Card 2</h2>
        <p>Popular selection</p>
      </div>
    </div>
  </div>
  <div class="carousel-item">
    <div class="card card-accent w-80">
      <div class="card-content">
        <h2 class="card-title">Card 3</h2>
        <p>Trending now</p>
      </div>
    </div>
  </div>
</div>

항목을 위에서 아래로 스크롤하기 위한 수직 캐러셀을 만듭니다.

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<div class="carousel carousel-vertical h-96 gap-2 p-2 bg-base-100">
  <div class="carousel-item h-32">
    <div class="badge badge-lg badge-primary">Item 1</div>
  </div>
  <div class="carousel-item h-32">
    <div class="badge badge-lg badge-secondary">Item 2</div>
  </div>
  <div class="carousel-item h-32">
    <div class="badge badge-lg badge-accent">Item 3</div>
  </div>
  <div class="carousel-item h-32">
    <div class="badge badge-lg badge-info">Item 4</div>
  </div>
</div>

앵커 링크를 사용하여 캐러셀 항목 간 수동 탐색을 위한 버튼을 추가합니다.

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<div class="carousel w-full">
  <div id="slide1" class="carousel-item relative w-full">
    <div class="badge badge-primary w-full h-32">Slide 1</div>
    <div class="absolute inset-x-0 top-1/2 flex justify-between px-2">
      <a href="#slide4" class="btn btn-circle btn-sm btn-ghost" aria-label="Previous slide"></a>
      <a href="#slide2" class="btn btn-circle btn-sm btn-ghost" aria-label="Next slide"></a>
    </div>
  </div>
  <div id="slide2" class="carousel-item relative w-full">
    <div class="badge badge-secondary w-full h-32">Slide 2</div>
    <div class="absolute inset-x-0 top-1/2 flex justify-between px-2">
      <a href="#slide1" class="btn btn-circle btn-sm btn-ghost" aria-label="Previous slide"></a>
      <a href="#slide3" class="btn btn-circle btn-sm btn-ghost" aria-label="Next slide"></a>
    </div>
  </div>
  <div id="slide3" class="carousel-item relative w-full">
    <div class="badge badge-accent w-full h-32">Slide 3</div>
    <div class="absolute inset-x-0 top-1/2 flex justify-between px-2">
      <a href="#slide2" class="btn btn-circle btn-sm btn-ghost" aria-label="Previous slide"></a>
      <a href="#slide4" class="btn btn-circle btn-sm btn-ghost" aria-label="Next slide"></a>
    </div>
  </div>
  <div id="slide4" class="carousel-item relative w-full">
    <div class="badge badge-info w-full h-32">Slide 4</div>
    <div class="absolute inset-x-0 top-1/2 flex justify-between px-2">
      <a href="#slide3" class="btn btn-circle btn-sm" aria-label="Previous slide">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>
      </a>
      <a href="#slide1" class="btn btn-circle btn-sm" aria-label="Next slide">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6"/></svg>
      </a>
    </div>
  </div>
</div>

여러 캐러셀 항목에 대한 탐색 표시기로 작은 배지 버튼을 사용합니다.

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<div class="carousel w-full">
  <div id="item1" class="carousel-item w-full">
    <div class="badge badge-primary w-full h-32">1</div>
  </div>
  <div id="item2" class="carousel-item w-full">
    <div class="badge badge-secondary w-full h-32">2</div>
  </div>
  <div id="item3" class="carousel-item w-full">
    <div class="badge badge-accent w-full h-32">3</div>
  </div>
  <div id="item4" class="carousel-item w-full">
    <div class="badge badge-info w-full h-32">4</div>
  </div>
  <div class="flex justify-center gap-2 pt-4">
    <a href="#item1" class="btn btn-xs btn-outline">1</a>
    <a href="#item2" class="btn btn-xs btn-outline">2</a>
    <a href="#item3" class="btn btn-xs btn-outline">3</a>
    <a href="#item4" class="btn btn-xs btn-outline">4</a>
  </div>
</div>

JS 및 반응 도우미

frutjam/jscreateCarousel 또는 frutjam/reactuseCarousel을 사용하여 프로그래밍 방식으로 슬라이드를 탐색하세요. 자동으로 prefers-reduced-motion을 존중합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<div class="flex gap-2 mb-3">
  <button class="btn btn-sm" id="carousel-prev">← Prev</button>
  <button class="btn btn-sm" id="carousel-next">Next →</button>
</div>
<div class="carousel w-full" id="js-carousel">
  <div class="carousel-item w-full"><div class="badge badge-primary w-full h-32">Slide 1</div></div>
  <div class="carousel-item w-full"><div class="badge badge-secondary w-full h-32">Slide 2</div></div>
  <div class="carousel-item w-full"><div class="badge badge-accent w-full h-32">Slide 3</div></div>
</div>
<script type="module">
  import { createCarousel } from 'frutjam/js'
  const carousel = createCarousel(document.getElementById('js-carousel'))
  document.getElementById('carousel-prev').onclick = () => carousel.prev()
  document.getElementById('carousel-next').onclick = () => carousel.next()
</script>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { useCarousel } from 'frutjam/react'

export default function CarouselDemo() {
  const carousel = useCarousel()
  return (
    <>
      <div className="flex gap-2 mb-3">
        <button className="btn btn-sm" onClick={carousel.prev}> Prev</button>
        <button className="btn btn-sm" onClick={carousel.next}>Next </button>
      </div>
      <div ref={carousel.ref} className="carousel w-full">
        <div className="carousel-item w-full"><div className="badge badge-primary w-full h-32">Slide 1</div></div>
        <div className="carousel-item w-full"><div className="badge badge-secondary w-full h-32">Slide 2</div></div>
        <div className="carousel-item w-full"><div className="badge badge-accent w-full h-32">Slide 3</div></div>
      </div>
    </>
  )
}

Claude Code, Cursor 또는 다른 AI 편집기를 사용하시나요?

Cherry MCP는 AI 편집기에 요청 시 정확한 회전목마 클래스 이름과 구조를 제공합니다. 더 이상 환각에 빠진 수업은 없습니다.

Cherry MCP를 사용해 보세요