Carousel

The Carousel component allows you to create interactive slideshows for cycling through elements like images, videos, or cards with intuitive navigation controls and smooth transitions.

Installation

Before using the Carousel component, make sure you have the required dependency installed:

npm install embla-carousel-svelte

Usage

<script>
  import { 
    Carousel,
    CarouselContent,
    CarouselItem,
    CarouselPrevious,
    CarouselNext
  } from "$lib/components/ui/carousel";
</script>

<Carousel>
  <CarouselContent>
    <CarouselItem>Item 1</CarouselItem>
    <CarouselItem>Item 2</CarouselItem>
    <CarouselItem>Item 3</CarouselItem>
  </CarouselContent>
  <CarouselPrevious />
  <CarouselNext />
</Carousel>

Examples

Basic Carousel

Here’s a basic example of a carousel with navigation buttons:

1
2
3
<Carousel className="w-full max-w-xs">
  <CarouselContent>
    <CarouselItem className="pl-1">
      <div className="p-1">
        <div className="flex aspect-square items-center justify-center rounded-md bg-primary p-6">
          <span className="text-3xl font-semibold text-primary-foreground">1</span>
        </div>
      </div>
    </CarouselItem>
    <CarouselItem className="pl-1">
      <div className="p-1">
        <div className="flex aspect-square items-center justify-center rounded-md bg-primary p-6">
          <span className="text-3xl font-semibold text-primary-foreground">2</span>
        </div>
      </div>
    </CarouselItem>
    <CarouselItem className="pl-1">
      <div className="p-1">
        <div className="flex aspect-square items-center justify-center rounded-md bg-primary p-6">
          <span className="text-3xl font-semibold text-primary-foreground">3</span>
        </div>
      </div>
    </CarouselItem>
  </CarouselContent>
  <div className="flex justify-end gap-1 py-2">
    <CarouselPrevious className="static translate-y-0 -translate-x-0" />
    <CarouselNext className="static translate-y-0 -translate-x-0" />
  </div>
</Carousel>

Multiple Items

A carousel showing multiple items per slide:

1
2
3
4
5
<Carousel className="w-full max-w-sm">
  <CarouselContent className="-ml-2 md:-ml-4">
    {#each Array(5) as _, i}
      <CarouselItem className="pl-2 md:pl-4 basis-1/2">
        <div className="p-1">
          <div className="flex aspect-square items-center justify-center rounded-md bg-secondary p-6">
            <span className="text-3xl font-semibold">{i + 1}</span>
          </div>
        </div>
      </CarouselItem>
    {/each}
  </CarouselContent>
  <div className="flex justify-end gap-1 py-2">
    <CarouselPrevious className="static translate-y-0 -translate-x-0" />
    <CarouselNext className="static translate-y-0 -translate-x-0" />
  </div>
</Carousel>

Film Cards Carousel

A carousel designed for displaying film cards:

Preview Image

The Silent Echo

Director: Alex Rivera

Drama 2023
Preview Image

Beyond the Horizon

Director: Sophia Chen

Sci-Fi 2023
Preview Image

Urban Rhythms

Director: Marcus Johnson

Documentary 2021
<Carousel className="w-full max-w-md">
  <CarouselContent>
    <CarouselItem>
      <div className="p-1">
        <div className="rounded-lg border shadow-sm overflow-hidden">
          <div className="aspect-video bg-muted relative">
            <div className="absolute inset-0 flex items-center justify-center bg-black/40 text-white font-medium">
              Preview Image
            </div>
          </div>
          <div className="p-4">
            <h3 className="font-medium text-lg">The Silent Echo</h3>
            <p className="text-sm text-muted-foreground">Director: Alex Rivera</p>
            <div className="flex items-center gap-2 mt-2">
              <Badge variant="secondary">Drama</Badge>
              <Badge variant="outline">2023</Badge>
            </div>
          </div>
        </div>
      </div>
    </CarouselItem>
    <!-- More CarouselItems... -->
  </CarouselContent>
  <div className="flex justify-center gap-2 py-2 mt-4">
    <CarouselPrevious className="static translate-y-0 -translate-x-0" />
    <CarouselNext className="static translate-y-0 -translate-x-0" />
  </div>
</Carousel>

Vertical Orientation

A carousel with vertical orientation:

1
2
3
<Carousel orientation="vertical" className="w-full max-w-xs h-[300px]">
  <CarouselContent className="h-full">
    <CarouselItem className="pt-1 h-full">
      <div className="p-1 h-full">
        <div className="flex items-center justify-center rounded-md bg-primary h-full p-6">
          <span className="text-3xl font-semibold text-primary-foreground">1</span>
        </div>
      </div>
    </CarouselItem>
    <!-- More Items... -->
  </CarouselContent>
  <div className="flex flex-col absolute -right-12 top-1/2 -translate-y-1/2 gap-1">
    <CarouselPrevious className="static translate-y-0 -translate-x-0 rotate-90" />
    <CarouselNext className="static translate-y-0 -translate-x-0 rotate-90" />
  </div>
</Carousel>

API Reference

Carousel Components

ComponentDescription
CarouselThe root container for the carousel.
CarouselContentThe container for carousel items.
CarouselItemThe individual carousel item.
CarouselPreviousThe previous button for the carousel.
CarouselNextThe next button for the carousel.

Carousel Properties

PropertyTypeDefaultDescription
orientation"horizontal" \| "vertical""horizontal"The orientation of the carousel.
optsCarouselOptions{}Options for the Embla Carousel.
pluginsCarouselPlugins[]Plugins for the Embla Carousel.
setApi(api: CarouselAPI \| undefined) => void() => {}Function to set the carousel API.
classstringundefinedAdditional CSS classes for the carousel.

CarouselContent Properties

PropertyTypeDefaultDescription
classstringundefinedAdditional CSS classes for the content container.

CarouselItem Properties

PropertyTypeDefaultDescription
classstringundefinedAdditional CSS classes for the item.

CarouselPrevious Properties

PropertyTypeDefaultDescription
variantButtonVariant"outline"The variant of the button.
sizeButtonSize"icon"The size of the button.
classstringundefinedAdditional CSS classes for the button.

CarouselNext Properties

PropertyTypeDefaultDescription
variantButtonVariant"outline"The variant of the button.
sizeButtonSize"icon"The size of the button.
classstringundefinedAdditional CSS classes for the button.

Carousel Options

The opts property accepts all options from the Embla Carousel library. Here are some of the most commonly used options:

OptionTypeDefaultDescription
loopbooleanfalseWhether the carousel should loop.
align"start" \| "center" \| "end""center"The alignment of the slide in the carousel.
dragFreebooleanfalseWhether the carousel should be draggable freely.
containScrollboolean \| "trimSnaps"falseWhether the carousel should contain the scroll.
slidesToScrollnumber1The number of slides to scroll at a time.

For a full list of options, refer to the Embla Carousel documentation.

Implementation Details

The Carousel component is built on top of the Embla Carousel library, providing a responsive and customizable carousel experience. The implementation uses Svelte’s context API to manage the carousel state and provide access to navigation methods.

<!-- Carousel implementation -->
<div class={cn("relative", className)} role="region" aria-roledescription="carousel">
  <slot />
</div>

<!-- CarouselContent implementation -->
<div class="overflow-hidden" use:emblaCarouselSvelte={{ options, plugins }} on:emblaInit>
  <div class={cn("flex", orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col")}>
    <slot />
  </div>
</div>

<!-- CarouselItem implementation -->
<div class={cn("min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "pl-4" : "pt-4")}>
  <slot />
</div>

The components are built with accessibility in mind, using proper ARIA attributes and keyboard navigation support.