Carousel
Cycle through slides with indicators, controls, captions, and autoplay behavior.
How it works
The carousel helper renders the Bootstrap carousel shell, captures bs-carousel-item children, and can generate indicators and controls from those captured items.
For performance, non-autoplaying carousels are initialized by Bootstrap when a user first activates a control or indicator. Autoplaying carousels initialize automatically, so do not initialize the same element twice from custom JavaScript.
Do not nest carousels. They can also create usability and accessibility issues, so prefer them for short, visual content rather than reading-heavy workflows.
- Set one item as active with
is-active="true". - Use
show-controlsandshow-indicatorsonbs-carouselwhen navigation is needed. - Use
intervalon individual items to tune automatic cycling per slide. - Use a unique
idwhenever controls or indicators target the carousel. - Autoplaying carousels with
data-bs-ride="carousel"initialize automatically; other carousels can be initialized through Bootstrap's JavaScript API. - Use Bootstrap
data-bs-*passthrough attributes on the helper when Bootstrap documents an option that BCL does not expose as a typed property.
Basic examples
Use the carousel helper for slides-only, controls, indicators, and captions examples. The helper captures each bs-carousel-item and renders the required carousel structure.
With controls
<bs-carousel id="carouselBasicControls" slide="true" show-controls="true">
<bs-carousel-item is-active="true">
<bs-div bg-color="Primary" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 12rem;">First slide</bs-div>
</bs-carousel-item>
<bs-carousel-item>
<bs-div bg-color="Success" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 12rem;">Second slide</bs-div>
</bs-carousel-item>
<bs-carousel-item>
<bs-div bg-color="Warning" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 12rem;">Third slide</bs-div>
</bs-carousel-item>
</bs-carousel>
With controls, indicators, and captions
<bs-carousel id="carouselWithControls" slide="true" show-controls="true" show-indicators="true">
<bs-carousel-item is-active="true" indicator-aria-label="Slide 1">
<bs-div bg-color="Primary" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 16rem;">
<bs-div text-alignment="Center">
<bs-heading heading-level="Three" heading-style-level="Five">First slide label</bs-heading>
<bs-p bottom-margin="None">Indicators and controls are generated by the carousel helper.</bs-p>
</bs-div>
</bs-div>
<bs-carousel-caption>
<bs-heading heading-level="Four" heading-style-level="Five">First slide label</bs-heading>
<bs-p>Captions are captured by the carousel item helper.</bs-p>
</bs-carousel-caption>
</bs-carousel-item>
<bs-carousel-item indicator-aria-label="Slide 2">
<bs-div bg-color="Info" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 16rem;">Second slide</bs-div>
<bs-carousel-caption>
<bs-heading heading-level="Four" heading-style-level="Five">Second slide label</bs-heading>
<bs-p>Controls move between testable slide states.</bs-p>
</bs-carousel-caption>
</bs-carousel-item>
<bs-carousel-item indicator-aria-label="Slide 3">
<bs-div bg-color="Warning" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 16rem;">Third slide</bs-div>
<bs-carousel-caption>
<bs-heading heading-level="Four" heading-style-level="Five">Third slide label</bs-heading>
<bs-p>Each indicator has an accessible label.</bs-p>
</bs-carousel-caption>
</bs-carousel-item>
</bs-carousel>
Indicators
Set show-indicators="true" to render indicator controls from the captured items. Indicators let users jump directly to a slide and should have clear per-slide accessible labels.
<bs-carousel id="carouselIndicatorsOnly" slide="true" show-indicators="true">
<bs-carousel-item is-active="true" indicator-aria-label="Indicator slide 1">
<bs-div bg-color="Primary" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">First slide</bs-div>
</bs-carousel-item>
<bs-carousel-item indicator-aria-label="Indicator slide 2">
<bs-div bg-color="Success" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Second slide</bs-div>
</bs-carousel-item>
<bs-carousel-item indicator-aria-label="Indicator slide 3">
<bs-div bg-color="Info" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Third slide</bs-div>
</bs-carousel-item>
</bs-carousel>
Captions
Add bs-carousel-caption inside an item. Bootstrap hides captions on smaller viewports unless you adjust the caption display classes.
<bs-carousel id="carouselCaptions" slide="true" show-controls="true">
<bs-carousel-item is-active="true">
<bs-div bg-color="Dark" bg-contrasts-text="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 14rem;">Slide with caption</bs-div>
<bs-carousel-caption display="None" display-md="Block">
<bs-heading heading-level="Three" heading-style-level="Five">Visible from md up</bs-heading>
<bs-p>The caption capture renders inside the active carousel item.</bs-p>
</bs-carousel-caption>
</bs-carousel-item>
<bs-carousel-item>
<bs-div bg-color="Secondary" bg-contrasts-text="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 14rem;">Second caption slide</bs-div>
<bs-carousel-caption display="None" display-md="Block">
<bs-heading heading-level="Three" heading-style-level="Five">Second caption</bs-heading>
<bs-p>Use normal heading and paragraph content.</bs-p>
</bs-carousel-caption>
</bs-carousel-item>
</bs-carousel>
Crossfade
Add Bootstrap's fade behavior to the helper when the carousel should fade between slides instead of sliding. Text-only slides may need additional height or custom styles so the crossfade has stable dimensions.
<bs-carousel id="carouselCrossfade" slide="true" fade="true" show-controls="true">
<bs-carousel-item is-active="true">
<bs-div bg-color="Danger" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 12rem;">Fade slide one</bs-div>
</bs-carousel-item>
<bs-carousel-item>
<bs-div bg-color="Success" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 12rem;">Fade slide two</bs-div>
</bs-carousel-item>
<bs-carousel-item>
<bs-div bg-color="Info" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 12rem;">Fade slide three</bs-div>
</bs-carousel-item>
</bs-carousel>
Autoplaying carousels
Set autoplay="true" when a carousel should begin cycling on page load. Autoplay pauses on hover by default, and browsers that support the Page Visibility API stop cycling while the page is hidden.
Autoplay should be used carefully. Prefer leaving users in control for reading-heavy content, and provide a visible way to pause or stop motion when content moves automatically.
<bs-carousel id="carouselAutoplay" autoplay="true" show-controls="true">
<bs-carousel-item is-active="true" interval="10000">
<bs-div bg-color="Secondary" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Slow first slide</bs-div>
</bs-carousel-item>
<bs-carousel-item interval="2000">
<bs-div bg-color="Primary" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Fast second slide</bs-div>
</bs-carousel-item>
<bs-carousel-item interval="5000">
<bs-div bg-color="Success" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Default-length third slide</bs-div>
</bs-carousel-item>
</bs-carousel>
Ride after interaction
Set data-bs-ride="true" when the carousel should begin cycling after the first user interaction instead of immediately on page load.
<bs-carousel id="carouselRideAfterInteraction" slide="true" show-controls="true" data-bs-ride="true">
<bs-carousel-item is-active="true">
<bs-div bg-color="Primary" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">First slide</bs-div>
</bs-carousel-item>
<bs-carousel-item>
<bs-div bg-color="Success" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Second slide</bs-div>
</bs-carousel-item>
<bs-carousel-item>
<bs-div bg-color="Warning" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Third slide</bs-div>
</bs-carousel-item>
</bs-carousel>
Individual .carousel-item interval
Set interval on a bs-carousel-item to render Bootstrap's per-item data-bs-interval attribute.
<bs-carousel id="carouselInterval" slide="true" autoplay="true" show-controls="true">
<bs-carousel-item is-active="true" interval="10000">
<bs-div bg-color="Secondary" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Ten second slide</bs-div>
</bs-carousel-item>
<bs-carousel-item interval="2000">
<bs-div bg-color="Primary" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Two second slide</bs-div>
</bs-carousel-item>
<bs-carousel-item>
<bs-div bg-color="Success" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Default interval slide</bs-div>
</bs-carousel-item>
</bs-carousel>
Autoplaying carousels without controls
Autoplay can run without visible controls, but this pattern should be reserved for decorative or low-risk content because users have no built-in pause, previous, or next control.
<bs-carousel id="carouselAutoplayNoControls" slide="true" autoplay="true">
<bs-carousel-item is-active="true" interval="3000">
<bs-div bg-color="Info" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Autoplay slide one</bs-div>
</bs-carousel-item>
<bs-carousel-item interval="3000">
<bs-div bg-color="Warning" bg-color-subtle="true" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Autoplay slide two</bs-div>
</bs-carousel-item>
</bs-carousel>
Dark variant
Bootstrap 5.3 prefers color modes for dark controls. Apply data-bs-theme="dark" on the helper or a parent wrapper when the slide content needs dark-themed controls and indicators.
<bs-carousel id="carouselDarkControls" slide="true" show-controls="true" show-indicators="true" data-bs-theme="dark">
<bs-carousel-item is-active="true" interval="10000" indicator-aria-label="Dark slide 1">
<bs-div bg-color="Light" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 12rem;">First slide</bs-div>
<bs-carousel-caption>
<bs-heading heading-level="Three" heading-style-level="Five">First slide label</bs-heading>
<bs-p>Some representative placeholder content for the first slide.</bs-p>
</bs-carousel-caption>
</bs-carousel-item>
<bs-carousel-item interval="2000" indicator-aria-label="Dark slide 2">
<bs-div display="Flex" align-items="Center" justify-content="Center" body-bg-color="Tertiary" borders="All" border-rounding="All" style="height: 12rem;">Second slide</bs-div>
<bs-carousel-caption>
<bs-heading heading-level="Three" heading-style-level="Five">Second slide label</bs-heading>
<bs-p>Some representative placeholder content for the second slide.</bs-p>
</bs-carousel-caption>
</bs-carousel-item>
<bs-carousel-item indicator-aria-label="Dark slide 3">
<bs-div bg-color="Light" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 12rem;">Third slide</bs-div>
<bs-carousel-caption>
<bs-heading heading-level="Three" heading-style-level="Five">Third slide label</bs-heading>
<bs-p>Some representative placeholder content for the third slide.</bs-p>
</bs-carousel-caption>
</bs-carousel-item>
</bs-carousel>
Disable touch swiping
The carousel helper does not expose a dedicated touch property. Use Bootstrap's data-bs-touch passthrough attribute on bs-carousel; the helper still owns the carousel shell, items, controls, and indicators.
<bs-carousel id="carouselNoTouch" slide="true" show-controls="true" data-bs-touch="false">
<bs-carousel-item is-active="true">
<bs-div bg-color="Light" display="Flex" align-items="Center" justify-content="Center" borders="All" border-rounding="All" style="height: 10rem;">Touch disabled</bs-div>
</bs-carousel-item>
<bs-carousel-item>
<bs-div display="Flex" align-items="Center" justify-content="Center" body-bg-color="Tertiary" borders="All" border-rounding="All" style="height: 10rem;">Second slide</bs-div>
</bs-carousel-item>
</bs-carousel>
Custom transition
Bootstrap customizes transition duration with Sass or compiled CSS. BCL does not add a carousel-specific transition-duration property, so keep duration changes in site CSS and continue using bs-carousel for the markup.
.carousel-item {
transition: transform .6s ease-in-out;
}
CSS
Sass variables
Bootstrap carousel control colors, indicator dimensions, caption spacing, icon filters, and transition timing are Sass-level customization points. Use BCL helpers for markup and keep those design tokens in the compiled stylesheet.
Usage
Bootstrap's JavaScript carousel plugin can be controlled with data attributes or JavaScript. BCL exposes common carousel properties such as autoplay, show-controls, show-indicators, and item interval; other Bootstrap options stay available through data-bs-* passthrough attributes on the helper.
Via data attributes
Use data-bs-* attributes on bs-carousel when Bootstrap documents a plugin option that BCL does not expose as a typed helper property. Keep the child slides as bs-carousel-item so indicators, captions, and controls remain helper-rendered.
<bs-carousel id="docsCarousel" autoplay="true" data-bs-interval="3000" data-bs-pause="hover">
<bs-carousel-item is-active="true">First slide</bs-carousel-item>
<bs-carousel-item>Second slide</bs-carousel-item>
</bs-carousel>
Via JavaScript
const carouselElement = document.querySelector('#docsCarousel');
const carousel = bootstrap.Carousel.getOrCreateInstance(carouselElement, {
interval: 3000,
ride: false
});
carousel.next();
Options
interval,keyboard,pause,ride,touch, andwrapare Bootstrap plugin options. Use helper properties where present, item attributes for per-slide behavior, anddata-bs-*passthrough otherwise.
<bs-carousel id="optionsCarousel" autoplay="true" data-bs-wrap="false" data-bs-keyboard="true">
<bs-carousel-item is-active="true" interval="3000">First slide</bs-carousel-item>
<bs-carousel-item interval="6000">Second slide</bs-carousel-item>
</bs-carousel>
Methods
Bootstrap carousel methods include cycle, pause, prev, next, to, and dispose. Invoke them through Bootstrap's JavaScript API against the helper-rendered carousel element.
const carousel = bootstrap.Carousel.getOrCreateInstance('#docsCarousel');
carousel.pause();
carousel.to(1);
carousel.cycle();
Events
Bootstrap emits slide.bs.carousel and slid.bs.carousel. The helper also exposes on-slide and on-slid event attributes for inline handler wiring.
<bs-carousel
id="docsCarouselEvents"
show-controls="true"
on-slide="console.log('sliding', from, to, direction)"
on-slid="console.log('active slide', to)">
<bs-carousel-item is-active="true">First slide</bs-carousel-item>
<bs-carousel-item>Second slide</bs-carousel-item>
</bs-carousel>
on-slide and on-slid attributes wire the Bootstrap slide.bs.carousel and slid.bs.carousel events; direct JavaScript listeners still work when an application needs centralized event handling.