Carousel

A slideshow component for cycling through elements—images or slides of text—like a carousel.

How it works

The carousel is a slideshow for cycling through a series of content, built with CSS 3D transforms and a bit of JavaScript. It works with a series of images, text, or custom markup. It also includes support for previous/next controls and indicators.

In browsers where the Page Visibility is supported, the carousel will avoid sliding when the webpage is not visible to the user (such as when the browser tab is inactive, the browser window is minimized, etc.).

Please be aware that nested carousels are not supported, and carousels are generally not compliant with accessibility standards.

Example

Adding in the previous and next controls. We recommend using control attribute.

vue
<template>
 <Carousel control>
  <CarouselInner>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/claudio-poggio-xCK8kr0R0JE-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/janosch-lino-k6w8miMpfUI-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/roman-bozhko-OXXsAafHDeo-unsplash.jpg"
    />
   </CarouselItem>
  </CarouselInner>
 </Carousel>
</template>

Indicators

You can add indicators to the carousel, alongside the previous/next controls. The indicators let users jump directly to a particular slide.

vue
<template>
 <Carousel
  control
  indicators
 >
  <CarouselInner>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/claudio-poggio-xCK8kr0R0JE-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/janosch-lino-k6w8miMpfUI-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/roman-bozhko-OXXsAafHDeo-unsplash.jpg"
    />
   </CarouselItem>
  </CarouselInner>
 </Carousel>
</template>

Captions

Add captions to your slides easily with the CarouselCaption element within any CarouselItem.

They can be easily hidden on smaller viewports, as shown below, with optional display utilities .

We hide them initially with display="none and bring them back on medium-sized devices with display="none.

vue
<template>
 <Carousel
  control
  indicators
 >
  <CarouselInner>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/claudio-poggio-xCK8kr0R0JE-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>First slide label</h5>
     <p>Some representative placeholder content for the first slide.</p>
    </CarouselCaption>
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/janosch-lino-k6w8miMpfUI-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>Second slide label</h5>
     <p>Some representative placeholder content for the second slide.</p>
    </CarouselCaption>
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/roman-bozhko-OXXsAafHDeo-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>Third slide label</h5>
     <p>Some representative placeholder content for the third slide.</p>
    </CarouselCaption>
   </CarouselItem>
  </CarouselInner>
 </Carousel>
</template>

Crossfade

Add fade attribute to your carousel to animate slides with a fade transition instead of a slide.

vue
<template>
 <Carousel
  fade
  control
 >
  <CarouselInner>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/claudio-poggio-xCK8kr0R0JE-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/janosch-lino-k6w8miMpfUI-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/roman-bozhko-OXXsAafHDeo-unsplash.jpg"
    />
   </CarouselItem>
  </CarouselInner>
 </Carousel>
</template>

Slides only

Here's a carousel with slides only.

Note the presence of the d-block and w-100 on carousel images to prevent browser default image alignment.

vue
<template>
 <Carousel>
  <CarouselInner>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/claudio-poggio-xCK8kr0R0JE-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/janosch-lino-k6w8miMpfUI-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/roman-bozhko-OXXsAafHDeo-unsplash.jpg"
    />
   </CarouselItem>
  </CarouselInner>
 </Carousel>
</template>

Individual CarouselItem interval

Add interval attribute to a CarouselItem component to change the amount of time to delay between automatically cycling to the next item.

vue
<template>
 <Carousel
  control
  indicators
 >
  <CarouselInner>
   <CarouselItem interval="10000">
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/claudio-poggio-xCK8kr0R0JE-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem interval="2000">
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/janosch-lino-k6w8miMpfUI-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/roman-bozhko-OXXsAafHDeo-unsplash.jpg"
    />
   </CarouselItem>
  </CarouselInner>
 </Carousel>
</template>

Disable touch swiping

Carousels support swiping left/right on touchscreen devices to move between slides.

This can be disabled using the touch attribute.

The example below also does not include the ride attribute and has touch="false" so it doesn't autoplay.

vue
<template>
 <Carousel
  touch="false"
  control
 >
  <CarouselInner>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/claudio-poggio-xCK8kr0R0JE-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/janosch-lino-k6w8miMpfUI-unsplash.jpg"
    />
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/roman-bozhko-OXXsAafHDeo-unsplash.jpg"
    />
   </CarouselItem>
  </CarouselInner>
 </Carousel>
</template>

Dark variant

Add dark attribute to the Carousel component for darker controls, indicators, and captions.

vue
<template>
 <Carousel
  dark
  control
  indicators
 >
  <CarouselInner>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/claudio-poggio-xCK8kr0R0JE-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>First slide label</h5>
     <p>Some representative placeholder content for the first slide.</p>
    </CarouselCaption>
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/janosch-lino-k6w8miMpfUI-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>Second slide label</h5>
     <p>Some representative placeholder content for the second slide.</p>
    </CarouselCaption>
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/roman-bozhko-OXXsAafHDeo-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>Third slide label</h5>
     <p>Some representative placeholder content for the third slide.</p>
    </CarouselCaption>
   </CarouselItem>
  </CarouselInner>
 </Carousel>
</template>

Methods

MethodDescription
cycle Circulate items from left to right
pause Stop circulating items
prev Circulate to previous item
next Circulate to next item
to Circulate to specific items

demo

vue
<template>
 <Carousel
  id="demoCarouselId"
  ref="demoCarousel"
 >
  <CarouselInner>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/claudio-poggio-xCK8kr0R0JE-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>First slide label</h5>
     <p>Some representative placeholder content for the first slide.</p>
    </CarouselCaption>
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/janosch-lino-k6w8miMpfUI-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>Second slide label</h5>
     <p>Some representative placeholder content for the second slide.</p>
    </CarouselCaption>
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/roman-bozhko-OXXsAafHDeo-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>Third slide label</h5>
     <p>Some representative placeholder content for the third slide.</p>
    </CarouselCaption>
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/daan-evers-tKN1WXrzQ3s-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>Fourth slide label</h5>
     <p>Some representative placeholder content for the third slide.</p>
    </CarouselCaption>
   </CarouselItem>
   <CarouselItem>
    <CarouselItemImage
     width="800"
     src="/unsplash/image/cafe/ceyda-ciftci-e-9eDRBH4S4-unsplash.jpg"
    />
    <CarouselCaption>
     <h5>Fifth slide label</h5>
     <p>Some representative placeholder content for the third slide.</p>
    </CarouselCaption>
   </CarouselItem>
  </CarouselInner>
 </Carousel>
 <b-button
  color="primary"
  @click="cycleClicked"
 >
  cycle
 </b-button>
 <b-button
  color="primary"
  @click="pauseClicked"
 >
  pause
 </b-button>
 <b-button
  color="secondary"
  @click="prevClicked"
 >
  ←prev
 </b-button>
 <b-button
  color="secondary"
  @click="nextClicked"
 >
  next→
 </b-button>
 <Dropdown margin="t-2">
  <DropdownToggle color="primary">
   To
  </DropdownToggle>
  <DropdownMenu>
   <DropdownItem
    v-for="n in 5"
    :key="n"
    @click="toClicked(n - 1)"
   >
    {{ n }}
   </DropdownItem>
  </DropdownMenu>
 </Dropdown>
</template>

<script setup lang="ts">
const demoCarousel = ref(null);
const toClicked = (id: number) => {
 if (demoCarousel.value) {
  demoCarousel.value.to(id);
 }
};

const cycleClicked = () => {
 if (demoCarousel.value) {
  demoCarousel.value.cycle();
 }
};
const pauseClicked = () => {
 if (demoCarousel.value) {
  demoCarousel.value.pause();
 }
};
const prevClicked = () => {
 if (demoCarousel.value) {
  demoCarousel.value.prev();
 }
};
const nextClicked = () => {
 if (demoCarousel.value) {
  demoCarousel.value.next();
 }
};
</script>