Carousel
A slideshow built on CSS scroll snapping: the browser handles sliding, swiping and momentum, and bootstrap-ng handles the active slide, controls, keyboard and autoplay.
Bootstrap’s carousel docs describe the markup and CSS.
Example
Put bsCarouselItem slides in a .carousel-inner. bsCarouselPrev and bsCarouselNext can go anywhere inside the carousel. Give the carousel an aria-label. Focus the carousel and use the arrow keys to move between slides. Screen readers announce the new slide, except while autoplay is on.
<div bsCarousel aria-label="Basic carousel">
<div class="carousel-inner">
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
First slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-3"
style="height: 240px">
Second slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
Third slide
</div>
</div>
</div>
<div class="d-flex justify-content-end mt-2">
<div>
<button type="button" class="btn-icon btn-sm" bsCarouselPrev>
<span class="carousel-icon-prev" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button type="button" class="btn-icon btn-sm" bsCarouselNext>
<span class="carousel-icon-next" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
</div>Indicators
Add bsCarouselIndicator buttons with the slide index in a .carousel-indicators element. Bind [(active)] to read or set the active slide.
Active slide: 1
<div bsCarousel aria-label="Carousel with indicators" [(active)]="slide">
<div class="carousel-inner">
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
First slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-3"
style="height: 240px">
Second slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
Third slide
</div>
</div>
</div>
<div class="d-flex justify-content-between align-items-center mt-2">
<div>
<button type="button" class="btn-icon btn-sm" bsCarouselPrev>
<span class="carousel-icon-prev" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button type="button" class="btn-icon btn-sm" bsCarouselNext>
<span class="carousel-icon-next" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
<div class="carousel-indicators">
@for (i of [0, 1, 2]; track i) {
<button
type="button"
[bsCarouselIndicator]="i"
[attr.aria-label]="`Slide ${i + 1}`"></button>
}
</div>
</div>
</div>
<p class="mt-2 mb-0">Active slide: {{ slide() + 1 }}</p>Overlay controls and crossfade
Add .carousel-overlay and wrap controls in .carousel-overlay-controls to place them over the slides. Add .carousel-fade to crossfade instead of sliding.
<div bsCarousel class="carousel-overlay carousel-fade" aria-label="Crossfading carousel">
<div class="carousel-inner">
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
First slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-3"
style="height: 240px">
Second slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
Third slide
</div>
</div>
</div>
<div class="carousel-overlay-controls">
<button type="button" class="btn-icon btn-sm" bsCarouselPrev>
<span class="carousel-icon-prev" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button type="button" class="btn-icon btn-sm" bsCarouselNext>
<span class="carousel-icon-next" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>Autoplay
autoplay cycles through the slides every interval milliseconds, pausing on hover and while the page is hidden. Using a control, an indicator, the keyboard or swiping stops autoplay for good. Always add a bsCarouselPlayPause button, as WCAG 2.2.2 requires a way to pause moving content.
<div bsCarousel autoplay [interval]="4000" aria-label="Autoplaying carousel">
<div class="carousel-inner">
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
First slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-3"
style="height: 240px">
Second slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
Third slide
</div>
</div>
</div>
<div class="d-flex justify-content-between align-items-center mt-2">
<div class="carousel-indicators">
@for (i of [0, 1, 2]; track i) {
<button
type="button"
[bsCarouselIndicator]="i"
[attr.aria-label]="`Slide ${i + 1}`"></button>
}
</div>
<div>
<button type="button" class="btn-icon btn-sm" bsCarouselPlayPause>
<span class="carousel-icon-pause" aria-hidden="true"></span>
<span class="carousel-icon-play" aria-hidden="true"></span>
</button>
<button type="button" class="btn-icon btn-sm" bsCarouselPrev>
<span class="carousel-icon-prev" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button type="button" class="btn-icon btn-sm" bsCarouselNext>
<span class="carousel-icon-next" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
</div>End behavior
By default (ends="loop") the carousel keeps sliding in the same direction past the last or first slide, onto the other end. wrap jumps back instead, which is also what loop does for layouts showing several slides and for users who prefer reduced motion. With ends="stop", shown here, the carousel stops at the first and last slide and disables the previous or next button there, moving focus to the other one.
<div bsCarousel ends="stop" aria-label="Carousel that stops at the ends">
<div class="carousel-inner">
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
First slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-3"
style="height: 240px">
Second slide
</div>
</div>
<div bsCarouselItem>
<div
class="d-flex align-items-center justify-content-center rounded-5 bg-2"
style="height: 240px">
Third slide
</div>
</div>
</div>
<div class="d-flex justify-content-end mt-2">
<div>
<button type="button" class="btn-icon btn-sm" bsCarouselPrev>
<span class="carousel-icon-prev" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button type="button" class="btn-icon btn-sm" bsCarouselNext>
<span class="carousel-icon-next" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
</div>API
BsCarousel
Selector: [bsCarousel] · Exported as: bsCarousel
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
active | number | 0 | Index of the active slide. Supports [(active)]. |
autoplay | boolean | false | Cycles through the slides. |
interval | number | 5000 | Milliseconds between slides while playing. |
pauseOnHover | boolean | true | Pauses autoplay while the pointer is over the carousel. |
ends | 'loop' | 'wrap' | 'stop' | 'loop' | What happens past the first and last slide. |
keyboard | boolean | true | Moves between slides with the arrow keys. |
id | string | generated | Element id, used by the controls for aria-controls. |
Outputs
| Name | Type | Description |
|---|---|---|
activeChange | number | Emits the new active slide index. |
Methods
| Name | Type | Description |
|---|---|---|
next() | void | Shows the next slide. |
prev() | void | Shows the previous slide. |
to(index) | void | Shows the slide at index. |
play() | void | Starts autoplay. |
pause() | void | Stops autoplay. |
isPlaying | Signal<boolean> | Whether autoplay is on. |
count | Signal<number> | Number of slides. |
lastIndex | Signal<number> | Index of the last slide that can scroll to the start. Lower than count - 1 when several slides are visible. |
BsCarouselItem
Selector: [bsCarouselItem] · Exported as: bsCarouselItem
BsCarouselPrev
Selector: [bsCarouselPrev]
BsCarouselNext
Selector: [bsCarouselNext]
BsCarouselIndicator
Selector: [bsCarouselIndicator]
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
bsCarouselIndicator | number | required | Index of the slide it shows. |
aria-label | string | Slide n | Accessible label. |
BsCarouselPlayPause
Selector: [bsCarouselPlayPause]
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
pauseLabel | string | 'Pause' | Accessible label while playing. |
playLabel | string | 'Play' | Accessible label while paused. |