<!-- Generated by tools/docs.php from docs/src/carousel.html - edit the source, not this file. -->

# Carousels

A row of slides seen one or a few at a time: tours, photos, reviews. The browser scrolls and snaps the row - a swipe, a wheel, the arrow keys - and the buttons move a slide back or on.

## Examples

`carousel` on the frame, a named region; `carousel-inner` on the row, which takes the focus; `carousel-item` on each slide. Buttons with `command="--prev"` or `"--next"` and `aria-controls` naming the carousel move a slide, round the ends. An empty `carousel-indicators` fills with a button per slide. The slide in place is `aria-current="true"`.

```html
<div class="carousel" id="carousel-basic-tours" role="region" aria-label="Tours">
	<div class="carousel-inner" tabindex="0" aria-label="Tours">
		<div class="carousel-item"><div class="p-24 bg-primary-subtle vstack gap-8"><strong>North Bay marine park</strong><span>Kayaks, a lagoon and a viewpoint, a day by speedboat.</span></div></div>
		<div class="carousel-item"><div class="p-24 bg-success-subtle vstack gap-8"><strong>Turtle Cove snorkeling</strong><span>Two bays and a coral garden, lunch on board.</span></div></div>
		<div class="carousel-item"><div class="p-24 bg-warning-subtle vstack gap-8"><strong>Sunset cruise</strong><span>A catamaran round the south coast at dusk.</span></div></div>
	</div>
	<div class="hstack gap-8 justify-content-between">
		<button class="btn btn-icon" type="button" command="--prev" aria-controls="carousel-basic-tours" aria-label="Previous"><i class="bi bi-chevron-left" aria-hidden="true"></i></button>
		<div class="carousel-indicators"></div>
		<button class="btn btn-icon" type="button" command="--next" aria-controls="carousel-basic-tours" aria-label="Next"><i class="bi bi-chevron-right" aria-hidden="true"></i></button>
	</div>
</div>
```

### Several at a time

Three custom properties on the carousel set the row, in the module's own stylesheet: `--redz-carousel-items` slides in view, `--redz-carousel-gap` between them and `--redz-carousel-peek` of the next one at the edges. `carousel-center` snaps a slide to the middle, `carousel-auto` lets each slide keep its own width.

```js
.tour-reviews { --redz-carousel-items: 2; --redz-carousel-gap: 12px; --redz-carousel-peek: 24px; }
```

```html
<div class="carousel" id="carousel-several-reviews" role="region" aria-label="Reviews">
	<div class="carousel-inner" tabindex="0" aria-label="Reviews">
		<div class="carousel-item"><div class="card card-body h-100">“The best day of our trip.” - Anna</div></div>
		<div class="carousel-item"><div class="card card-body h-100">“Kind guides and a clean boat.” - Mark</div></div>
		<div class="carousel-item"><div class="card card-body h-100">“The lagoon is worth the climb.” - Somchai</div></div>
		<div class="carousel-item"><div class="card card-body h-100">“Lunch was a surprise, a good one.” - Leila</div></div>
	</div>
	<div class="hstack gap-8 justify-content-end">
		<button class="btn btn-icon btn-sm" type="button" command="--prev" aria-controls="carousel-several-reviews" aria-label="Previous"><i class="bi bi-chevron-left" aria-hidden="true"></i></button>
		<button class="btn btn-icon btn-sm" type="button" command="--next" aria-controls="carousel-several-reviews" aria-label="Next"><i class="bi bi-chevron-right" aria-hidden="true"></i></button>
	</div>
</div>
```

### One at a time, fading, playing

`carousel-fade` stacks the slides and shows the current one. `carousel-overlay` lays its buttons over the slides. A button with `command="--play"` plays the slides on every 5 seconds while it is `aria-pressed="true"` - written so, it plays from the start - and pauses while the pointer rests on the carousel or the focus is in it; it never plays for a person who asks for less motion.

```html
<div class="carousel carousel-fade" id="carousel-fade-island" role="region" aria-label="The island">
	<div class="carousel-inner" tabindex="0" aria-label="The island">
		<div class="carousel-item"><div class="p-32 bg-info-subtle text-center"><strong>Beaches</strong></div></div>
		<div class="carousel-item"><div class="p-32 bg-success-subtle text-center"><strong>Waterfalls</strong></div></div>
		<div class="carousel-item"><div class="p-32 bg-warning-subtle text-center"><strong>Temples</strong></div></div>
	</div>
	<div class="carousel-overlay">
		<button class="btn btn-icon btn-sm" type="button" command="--prev" aria-controls="carousel-fade-island" aria-label="Previous"><i class="bi bi-chevron-left" aria-hidden="true"></i></button>
		<button class="btn btn-icon btn-sm" type="button" command="--next" aria-controls="carousel-fade-island" aria-label="Next"><i class="bi bi-chevron-right" aria-hidden="true"></i></button>
	</div>
	<div class="hstack gap-8 justify-content-center">
		<button class="btn btn-icon btn-sm btn-text" type="button" command="--play" aria-controls="carousel-fade-island" aria-pressed="false" aria-label="Play the slides"><i class="bi bi-play-fill" aria-hidden="true"></i><i class="bi bi-pause-fill" aria-hidden="true"></i></button>
		<div class="carousel-indicators"></div>
	</div>
</div>
```

## Keyboard and accessibility

- The carousel is a named region and each slide a group named by the page's text `slide` - “2 of 5”; an indicator button says the same, the current one `aria-current="true"`.
- The row takes the focus (`tabindex="0"` and a name): the arrow keys scroll it, a slide at a time in a fading carousel.
- A slide a person moves to by a button is told politely in a status of the carousel; nothing is told while it plays.
- The play button is a toggle button, pressed while it plays; the pointer resting on the carousel, the focus inside it and a hidden page pause it (WCAG 2.2.2).
- The buttons have no `commandfor`, which WebKit would announce as collapsed; their icons mirror right to left. An indicator is a 24 px target round its dot.

## Tokens

From [`css/components/carousel.css`](https://github.com/redz-tech/REDZ.UI/blob/main/css/components/carousel.css). It declares `--redz-carousel-items`, `--redz-carousel-gap`, `--redz-carousel-peek` on its root, never on rows or items.

It reads the theme's `--redz-space-12`, `--redz-radius-12`, `--redz-space-8`, `--redz-border-strong`, `--redz-text`, `--redz-ease`.

## From Bootstrap 5.3

| Bootstrap 5.3 | REDZ.UI | Change | Note |
| --- | --- | --- | --- |
| `carousel-caption` | - | review | the slide's own text, laid out with utilities |
| `carousel-control-next` | - | review | a btn btn-icon with command="--next" and aria-controls naming the carousel |
| `carousel-control-next-icon` | `bi bi-chevron-right` | rename | mirrored right to left |
| `carousel-control-prev` | - | review | a btn btn-icon with command="--prev" and aria-controls naming the carousel |
| `carousel-control-prev-icon` | `bi bi-chevron-left` | rename | mirrored right to left |
| `carousel-dark` | - | review | data-theme="dark" on the carousel |
| `carousel-item-end` | - | remove | the browser scrolls the row |
| `carousel-item-next` | - | remove | the browser scrolls the row |
| `carousel-item-prev` | - | remove | the browser scrolls the row |
| `carousel-item-start` | - | remove | the browser scrolls the row |
| `data-bs-slide="prev"` | `command="--prev" aria-controls="ID"` | trigger | the id of the carousel, without commandfor |
| `data-bs-slide="next"` | `command="--next" aria-controls="ID"` | trigger | the id of the carousel, without commandfor |
| `data-bs-slide-to` | - | remove | an empty carousel-indicators makes its buttons |
| `data-bs-ride` | `command="--play" aria-pressed="true"` | review | a play button pressed from the start, which a person who asks for less motion never sees play |
| `data-bs-interval` | - | remove | slides turn every 5 seconds |
| `bootstrap.Carousel` | `the --prev and --next buttons` | review | or scrollBy on carousel-inner; the row scrolls by the browser |
