The Carousel cycles through images or content with smooth transitions. It supports auto-play, swipe gestures, controls, and indicators, and is fully customizable.
| Class Name | Type | Description |
|---|---|---|
| carousel | Component | Carousel |
| carousel-inner | Inner | Carousel inner |
| carousel-item | Inner | Carousel item |
| carousel-control-prev | Inner | Carousel next button |
| carousel-control-next | Inner | Carousel previous button |
| carousel-control-prev-icon | Inner | Previous icon |
| carousel-control-next-icon | Inner | Next icon |
| carousel-indicators | Inner | Carousel indicator |
| carousel-caption | Inner | Carousel caption |
| carousel-fade | Modifier | Carousel fade animation |
The carousel functions as a slideshow, designed for cycling through various content, whether images, text, or custom markup. Its foundation involves CSS 3D transforms and a small amount of JavaScript. It also incorporates support for previous/next navigation controls and indicators.
For optimal performance, carousels require manual initialization using the carousel constructor method. Without this initialization, certain event listeners—specifically those needed for touch and swipe support—will not be registered until a user explicitly activates a control or an indicator.
The sole exception to this is autoplaying carousels that include the data-bs-ride="carousel" attribute; these are automatically initialized upon page load. If using autoplaying carousels with this data attribute, avoid explicitly initializing those same carousels with the constructor method.
Nested carousels are not supported. Additionally, it is important to note that carousels, in general, can frequently present usability and accessibility challenges.
Basic carousel with three slides and prev/next controls. Use <button> elements (recommended) or <a role="button">
HTML
<div id="carouselExample" class="carousel slide">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExample" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExample" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="hidden">Next</span>
</button>
</div>Add indicators with prev/next controls to let users jump to specific slides.
HTML
<div id="carouselExampleIndicators" class="carousel slide">
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1" aria-label="Slide 2"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2" aria-label="Slide 3"></button>
</div>
<div class="carousel-inner">
<div class="carousel-item active">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="hidden">Next</span>
</button>
</div>Add captions with .carousel-caption inside any .carousel-item. Control their visibility using display utility classes, hide them by default with .hidden, then show on medium and larger screens with .md:block. This keeps captions hidden on small devices but visible on bigger ones.
HTML
<div id="carouselExampleCaptions" class="carousel slide">
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="1" aria-label="Slide 2"></button>
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="2" aria-label="Slide 3"></button>
</div>
<div class="carousel-inner">
<div class="carousel-item active">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
<div class="carousel-caption hidden md:block">
<h5 class="text-lg font-semibold mb-0">First slide label</h5>
<p class="mb-0">Some representative placeholder content for the first slide.</p>
</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
<div class="carousel-caption hidden md:block">
<h5 class="text-lg font-semibold mb-0">Second slide label</h5>
<p class="mb-0">Some representative placeholder content for the second slide.</p>
</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
<div class="carousel-caption hidden md:block">
<h5 class="text-lg font-semibold mb-0">Third slide label</h5>
<p class="mb-0">Some representative placeholder content for the third slide.</p>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="hidden">Next</span>
</button>
</div>Use .carousel-fade to enable a fade transition between slides. For text-only or similar content, apply .bg-default or Tailwind utility classes to .carousel-item for proper crossfading.
HTML
<div id="carouselExampleFade" class="carousel slide carousel-fade">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="hidden">Next</span>
</button>
</div>Enable autoplay on page load by setting the ride option to carousel. By default, autoplay pauses when the carousel is hovered. This behavior can be adjusted using the pause option.
HTML
<div id="carouselExampleAutoplaying" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleAutoplaying" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleAutoplaying" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="hidden">Next</span>
</button>
</div>When the ride option is set to true instead of carousel, the carousel does not start cycling automatically on page load. Instead, it begins only after the first user interaction.
HTML
<div id="carouselExampleRide" class="carousel slide" data-bs-ride="true">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleRide" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleRide" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="hidden">Next</span>
</button>
</div>Use data-bs-interval="" on a .carousel-item to set the delay before it automatically cycles to the next item.
HTML
<div id="carouselExampleInterval" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active" data-bs-interval="10000">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
</div>
<div class="carousel-item" data-bs-interval="2000">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleInterval" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleInterval" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="hidden">Next</span>
</button>
</div>This example shows a carousel with slides only, without navigation controls. When using images inside the carousel, apply block and .w-full to ensure proper alignment and full-width display.
HTML
<div id="carouselExampleSlidesOnly" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
</div>
</div>
</div>On touch devices, carousels support swipe gestures to navigate between slides. To disable this behavior, set the touch option to false when initializing the carousel.
HTML
<div id="carouselExampleControlsNoTouching" class="carousel slide" data-bs-touch="false">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControlsNoTouching" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleControlsNoTouching" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="hidden">Next</span>
</button>
</div>HTML
<div id="customNextPrevIconExample" class="carousel slide">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="bg-emphasis/80 h-100 flex items-center justify-center text-4xl text-muted">Slide One</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/90 h-100 flex items-center justify-center text-4xl text-muted">Slide Two</div>
</div>
<div class="carousel-item">
<div class="bg-emphasis/70 h-100 flex items-center justify-center text-4xl text-muted">Slide Three</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#customNextPrevIconExample" data-bs-slide="prev">
<svg class="text-primary" xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24"><path fill="currentColor" d="m7.85 13l2.85 2.85q.3.3.288.7t-.288.7q-.3.3-.712.313t-.713-.288L4.7 12.7q-.3-.3-.3-.7t.3-.7l4.575-4.575q.3-.3.713-.287t.712.312q.275.3.288.7t-.288.7L7.85 11H19q.425 0 .713.288T20 12t-.288.713T19 13z"/></svg>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#customNextPrevIconExample" data-bs-slide="next">
<svg class="text-primary" xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24"><path fill="currentColor" d="M16.15 13H5q-.425 0-.712-.288T4 12t.288-.712T5 11h11.15L13.3 8.15q-.3-.3-.288-.7t.288-.7q.3-.3.713-.312t.712.287L19.3 11.3q.15.15.213.325t.062.375t-.062.375t-.213.325l-4.575 4.575q-.3.3-.712.288t-.713-.313q-.275-.3-.288-.7t.288-.7z"/></svg>
</button>
</div>The carousel component is built using a set of CSS variables. These variables provide flexibility for customizing styles.
.carousel {
--carousel-transition-duration: 0.6s;
--carousel-control-width: 15%;
--carousel-control-color: var(--color-contrast);
--carousel-control-opacity: 0.5;
--carousel-control-hover-opacity: 0.9;
--carousel-control-icon-width: 2rem;
--carousel-control-icon-height: 2rem;
--carousel-control-prev-icon-bg: ...;
--carousel-control-next-icon-bg: ...;
--carousel-indicator-width: 1.875rem;
--carousel-indicator-height: 0.1875rem;
--carousel-indicator-spacer: --spacing(0.75);
--carousel-indicator-active-bg: var(--color-contrast);
--carousel-indicator-hit-area-height: 0.625rem;
--carousel-indicator-opacity: 0.5;
--carousel-indicator-active-opacity: 1;
--carousel-caption-width: 70%;
--carousel-caption-spacer: --spacing(5);
--carousel-caption-padding-y: --spacing(5);
--carousel-caption-color: var(--color-contrast);
}Data attributes provide a straightforward method for controlling the carousel’s position. The data-bs-slide attribute accepts the keywords prev or next, which adjust the slide’s position relative to its current state. Alternatively, data-bs-slide-to can be used to pass a specific slide index to the carousel, for example, data-bs-slide-to="2", which moves the slide position to a particular index starting from 0.
Use JavaScript in the familiar pattern of Bootstrap’s plugins with full additional TypeScript Support.
Manual instantiation of the carousel is performed with:
const carousel = new hummingbird.Carousel('#myCarousel')Options can be provided through data attributes or via JavaScript. When using data-bs-attributes, append the option’s name, as in data-bs-animation="{value}". It is essential to convert “camelCase” option names to “kebab-case” when passing options via data attributes. For example, data-bs-custom-class="beautifier" should be used instead of data-bs-customClass="beautifier".
Carousel component support data-bs-config data attribute. This attribute can contain simple component configurations as a JSON string. If an element has both data-bs-config='{"delay":0, "title":123}' and data-bs-title="456" attributes, the final title value will be 456, as separate data attributes override values provided within data-bs-config. Additionally, existing data attributes can also house JSON values, such as data-bs-delay='{"show":0,"hide":150}'.
The final configuration object results from merging data-bs-config, individual data-bs-attributes, and JavaScript objects, where the latest provided key-value pair takes precedence over others.
| Name | Type | Default | Description |
|---|---|---|---|
interval | number | 5000 | Defines the duration in milliseconds to delay between automatically cycling items. |
keyboard | boolean | true | Determines whether the carousel responds to keyboard events. |
pause | string, boolean | "hover" | If set to "hover", it pauses the carousel’s cycling on mouseenter and resumes on mouseleave. If set to false, hovering over the carousel will not pause it. On touch-enabled devices, when set to "hover", cycling pauses on touchend (after user interaction) for two intervals before automatically resuming. This occurs in addition to the mouse behavior. |
ride | string, boolean | false | If set to true, the carousel autoplays after a user manually cycles the first item. If set to "carousel", the carousel autoplays upon loading. |
touch | boolean | true | Controls whether the carousel supports left/right swipe interactions on touchscreen devices. |
wrap | boolean | true | Determines whether the carousel cycles continuously or has defined start and end points. |
A carousel instance can be created with the carousel constructor, along with any additional options. For example, to manually initialize an autoplaying carousel (without using the data-bs-ride="carousel" attribute in the markup) with a specific interval and disabled touch support:
const myCarouselElement = document.querySelector('#myCarousel')
const carousel = new hummingbird.Carousel(myCarouselElement, {
interval: 2000,
touch: false
})| Method | Description |
|---|---|
cycle | Initiates cycling through the carousel items from left to right. |
dispose | Destroys an element’s carousel functionality, removing stored data from the DOM element. |
getInstance | A static method for retrieving the carousel instance associated with a DOM element. Usage: hummingbird.Carousel.getInstance(element). |
getOrCreateInstance | A static method that returns an existing carousel instance for a DOM element or creates a new one if it has not been initialized. Usage: hummingbird.Carousel.getOrCreateInstance(element). |
next | Advances to the next item in the carousel. It returns to the caller before the next item has been displayed (e.g., before the slid.bs.carousel event occurs). |
nextWhenVisible | Prevents the carousel from cycling to the next item if the page, the carousel itself, or the carousel’s parent is not visible. It returns to the caller before the target item has been shown. |
pause | Halts the carousel from cycling through items. |
prev | Cycles to the previous item in the carousel. It returns to the caller before the previous item has been displayed (e.g., before the slid.bs.carousel event occurs). |
to | Cycles the carousel to a specific frame (0-based index, similar to an array). It returns to the caller before the target item has been displayed (e.g., before the slid.bs.carousel event occurs). |
Carousel class exposes two events, providing opportunities to integrate with its functionality. Both events include the following additional properties:
direction: Indicates the direction in which the carousel is sliding (either "left" or "right").relatedTarget: Refers to the DOM element that is moving into place as the active item.from: Represents the index of the current item.to: Represents the index of the next item.All carousel events are dispatched at the carousel element itself (i.e., the <div class="carousel">).
| Event type | Description |
|---|---|
slid.bs.carousel | This event fires after the carousel has completed its slide transition. |
slide.bs.carousel | This event fires immediately when the slide instance method is invoked. |
Example event listener:
const myCarousel = document.getElementById('myCarousel')
myCarousel.addEventListener('slide.bs.carousel', event => {
// do something...
})