Skip to content

Data display

ICarousel ​

A row of slides you page through — screenshots, customer stories, a shelf of cards. Arrows, dots and the arrow keys.

Each item is rendered through the default slot, which receives item, index and active.

Scrolling ​

The slides sit in an overflow-x-auto row with CSS scroll snapping, so touch, trackpad, shift-scroll and a dragged scrollbar move the track as well as the arrows do.

The active slide is read back from the scroll position, so swiping by hand keeps the dots in step.

More than one across ​

perView sets how many fit at the widest. Below sm it is always one.

'auto' leaves each slide at its content's own width.

Arrows and dots ​

Both are on by default. The arrows disable at each end, and disappear when everything already fits.

There is one dot per place the track can stop at, not per slide: with several across, the last slides never reach the start of the track. The row is hidden when there is only one stop.

vue
<ICarousel :items="shots" :dots="false" label="Screens" />

No autoplay ​

There is none. Build one from v-model:active and a timer you own; setting the model scrolls the track.

Three things come with you: a pause control, for WCAG 2.2.2; a stop under prefers-reduced-motion; and a hold while a pointer or the keyboard focus is inside.

Wrapping with % shots.length only works while one slide is in view. With perView above one, wrap at the last position the dots offer instead.

Styling the active slide ​

The slide in view and its dot both carry data-state="active", the rest "inactive":

vue
<ICarousel :items="shots" :ui="{ item: 'opacity-40 data-[state=active]:opacity-100' }" />

Accessibility ​

The carousel is a group with aria-roledescription="carousel", and each slide is a group labelled "2 of 5". Give label something that names this carousel — "Customer stories", not "Carousel".

The track is focusable, and left and right move a slide at a time.

There is no live region.

Props ​

PropTypeDefaultDescription
itemsItem[]—One slide each, rendered through the default slot
perView1 | 2 | 3 | 4 | 'auto'1How many fit across at the widest
gap'none' | 'sm' | 'md' | 'lg''md'Space between slides
arrowsbooleantrueShow the previous and next buttons
dotsbooleantrueShow the row of dots
labelstring'Carousel'Accessible name
previousLabelstring'Previous'Accessible name for the back button
nextLabelstring'Next'Accessible name for the forward button
unstyledboolean—Drop built-in classes
classstring—Merged with the built-in classes
ui{ root?, viewport?, track?, item?, control?, dots?, dot? }—Per-element class overrides

Slots ​

SlotDescription
defaultOne slide. Receives item, index and active

Models ​

ModelTypeDescription
activenumberIndex of the slide at the start of the track. Reads back from the scroll position, and scrolls the track when set from outside