Carousel
A row of slides the user can swipe or step through.
When to use
- A set of images or cards users browse one at a time, where missing one is fine.
When not to use
- Content everyone must see: lay it out on the page.
- Views of the same subject: use Tabs.
Install
npx shadcn@latest add @clinia/carousel


Anatomy


- 1Region
data-slot="carousel"role=region - 2Slide
data-slot="carousel-item"basis-full · pl-4 - 3Previous
data-slot="carousel-previous"outline · icon-sm - 4Next
data-slot="carousel-next"outline · icon-sm
Clinia rules
- Never add autoplay: slides that move on their own fail WCAG 2.2.2.
- Previous and next are
outlineicon-smbuttons outside the slides. Leave 48px on each side for them. - The buttons disable at the first and last slide, unless you pass
opts={{ loop: true }}.
Accessibility
Built in
- The previous and next buttons are labelled and keyboard-reachable; the carousel never auto-advances.
- The root is
role="region"witharia-roledescription="carousel", and each slide isrole="group"witharia-roledescription="slide". - Arrow Left and Arrow Right move between slides while focus is inside the carousel.
Your responsibility
- Give the carousel an
aria-label, such asClinic photos: the region has no name by default. - Label each slide with its position, such as
aria-label="2 of 5". - Give each slide image its own
alttext. - If slides hold links or buttons, keep the hidden slides out of the tab order.
How to test
- Press Tab to the next button, then Enter: the next slide shows.
- With focus inside the carousel, press Arrow Right and Arrow Left: it moves one slide each way.
- With a screen reader, the region is announced as a carousel with its label, and each slide as a slide.
- Wait on a slide: nothing moves on its own.
API
| Prop | Values | Default | Description |
|---|---|---|---|
| opts | Partial<OptionsType> | – | Embla options, such as |
| plugins | CreatePluginType<LoosePluginType, {}>[] | – | Embla plugins. Don't add autoplay: slides that move on their own fail WCAG 2.2.2. |
| orientation | horizontalvertical | horizontal | Slide direction. |
| setApi | ((api: CarouselApi) => void) | – | Receives the Embla API, to build your own dots or read the current slide. |
All other props come from Embla Carousel.
Related