Carousel
import { Carousel } from '@absoluteui/components/carousel';import '@absoluteui/components/button/style.css';Using Angular? See Carousel for Angular.
What it does
Section titled “What it does”Shows one slide at a time from a set, such as featured items, an onboarding tour, or images, following the WAI-ARIA APG carousel pattern. The carousel is a named region with the role description “carousel”; each slide is a group labelled “N of M”; previous, next, and slide picker buttons move between slides; and slides that are not shown are inert, so focus never lands in a hidden slide. Autoplay is off by default. When it is on, a pause button comes first, rotation pauses on hover and focus, and it does not start for users who prefer reduced motion.
When to use
Section titled “When to use”- A few related items of equal weight that do not all need to be visible at once.
- A short step-through such as an onboarding tour.
When not to use
Section titled “When not to use”- Important content every user must see (most users never see slides after the first).
- Many items: use a list or a grid.
- Navigation between views: use Tabs.
Examples
Section titled “Examples”Featured items
Section titled “Featured items”import { Carousel } from '@absoluteui/components/carousel';import { Card } from '@absoluteui/components/card';
const slides = [ ['Spring sale', '20% off garden furniture until Sunday.'], ['New arrivals', 'The summer collection is here.'], ['Free delivery', 'On every order over 50 EUR.'],].map(([title, content]) => { const host = document.createElement('div'); Card.create(host, { title: title ?? '', content: content ?? '' }); return { content: host, label: title ?? '' };});const host = document.createElement('section');document.body.append(host);Carousel.create(host, { label: 'Featured', slides, loop: true });Autoplay with a pause button
Section titled “Autoplay with a pause button”import { Carousel } from '@absoluteui/components/carousel';
const host = document.createElement('section');document.body.append(host);// Rotation pauses on hover and focus, and does not start for users who prefer reduced motion.Carousel.create(host, { label: 'Announcements', autoplay: 6000, loop: true, slides: [ { content: 'The office is closed on Monday for the public holiday.' }, { content: 'Benefits enrollment closes on the 30th.' }, { content: 'Welcome to the 12 people who joined this month.' }, ],});import { Carousel } from '@absoluteui/components/carousel';import '@absoluteui/components/button/style.css';import '@absoluteui/components/carousel/style.css';
const host = document.querySelector<HTMLElement>('#quotes');if (host) Carousel.create(host, { label: 'Customer quotes', loop: true, slides: [{ content: 'Fast and reliable.' }, { content: 'Great support.' }] });More usage
Section titled “More usage”import { Carousel, type CarouselChangeDetail } from '@absoluteui/components/carousel';
const host = document.querySelector<HTMLElement>('#tour');if (host) { Carousel.create(host, { label: 'Product tour', slides: [{ content: 'Welcome' }, { content: 'Create a project' }, { content: 'Invite your team' }] }); host.addEventListener('aui-change', (event) => { const { index } = (event as CustomEvent<CarouselChangeDetail>).detail; host.dataset.step = String(index + 1); });}Anatomy
Section titled “Anatomy”<section class="aui-carousel" role="region" aria-roledescription="carousel" aria-label="Featured"> <button class="aui-carousel__pause">Pause</button> (autoplay only) <div class="aui-carousel__viewport" aria-live="polite|off"> <div class="aui-carousel__track"> <div class="aui-carousel__slide" role="group" aria-roledescription="slide" aria-label="1 of 3: Spring sale">content</div> <div class="aui-carousel__slide" ... inert>...</div> </div> </div> <div class="aui-carousel__controls"> <button class="aui-carousel__prev" aria-label="Previous slide"></button> <div class="aui-carousel__picker" role="group" aria-label="Slides"><button class="aui-carousel__dot" aria-label="Go to slide 1" aria-current="true"></button> ...</div> <button class="aui-carousel__next" aria-label="Next slide"></button> </div></section>API reference
Section titled “API reference”Factory
Section titled “Factory”Carousel.create(host: HTMLElement, options: CarouselOptions): CarouselGlobal configuration key: carousel (see Configuration).
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
label |
string |
Accessible name of the carousel. Required. | |
slides |
readonly CarouselSlide[] |
Slides: { content: Node | string, label? } (1 to 100). Required. | |
index |
number |
"0" |
Current slide (0-based). |
loop |
boolean |
"false" |
Wrap from the last slide to the first and back. |
autoplay |
number | null |
"null" |
Rotation interval in milliseconds (at least 2000), or null. |
showPicker |
boolean |
"true" |
Show the slide picker buttons. Globally configurable. |
locale |
string |
"en-US" |
Locale of the control labels and slide positions. Globally configurable. Inherited from common configuration. |
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
host |
HTMLElement |
The host element (role=region). |
index |
number |
Current slide (0-based). |
rotating |
boolean |
Whether automatic rotation is running now. |
options |
Readonly<CarouselOptions> |
Current options. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
goTo(index: number): void |
Show a slide (no event); clamped, or wrapped with loop. |
next(): void |
Show the next slide (no event). |
previous(): void |
Show the previous slide (no event). |
update(options: Partial<CarouselOptions>): void |
Merge and apply options. |
destroy(): void |
Stop rotation and remove rendering, attributes, and listeners. |
Events
Section titled “Events”| Event | Detail | Bubbles | Cancelable | Description |
|---|---|---|---|---|
aui-change |
CarouselChangeDetail |
Yes | No | The user moved to another slide: { index }. |
Content areas
Section titled “Content areas”| Area | Description |
|---|---|
slides |
Each slide’s content (Node or text). |
CSS classes
Section titled “CSS classes”All rules live in the aui.components cascade layer, so application styles override them without specificity battles.
| Class | Purpose |
|---|---|
aui-carousel |
Host (role=region, roledescription carousel). |
aui-carousel--autoplay | --animated |
Autoplay configured; transitions enabled after the first move. |
aui-carousel__pause |
Pause/play button (first; autoplay only). |
aui-carousel__viewport |
Clips the track; the live region. |
aui-carousel__track |
Slides side by side. |
aui-carousel__slide | __slide--current |
A slide (role=group, roledescription slide) and the current one. |
aui-carousel__controls |
Previous, picker, next. |
aui-carousel__prev | __next |
Previous and next buttons. |
aui-carousel__picker |
Slide picker group. |
aui-carousel__dot | __dot--current |
A picker button and the current one. |
Design tokens
Section titled “Design tokens”Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.
--aui-color-primary | --aui-duration-fast | --aui-easing-standard | --aui-radius-md | --aui-radius-pill | --aui-space-1 | --aui-space-2 | --aui-space-3
TypeScript definitions
Section titled “TypeScript definitions”interface CarouselConfig { showPicker: boolean }interface CarouselSlide { content: Node | string; label?: string }interface CarouselOptions extends Partial<CarouselConfig> { label: string; slides: readonly CarouselSlide[]; index?: number; loop?: boolean; autoplay?: number | null; locale?: string;}interface CarouselChangeDetail { index: number }Accessibility
Section titled “Accessibility”Pattern: WAI-ARIA APG Carousel (basic, with slide picker buttons): region with aria-roledescription ‘carousel’, slides as groups with aria-roledescription ‘slide’ and ‘N of M’ labels, rotation control first.
Keyboard
Section titled “Keyboard”| Key | Context | Action |
|---|---|---|
| Tab | Carousel | Pause button (with autoplay), the current slide’s content, previous, picker buttons, next. |
| Enter / Space | Buttons | Activate. |
| Element | Role |
|---|---|
| host | region (aria-roledescription ‘carousel’) |
| slide | group (aria-roledescription ‘slide’) |
| pause, previous, next, picker | button (native) |
| picker | group |
ARIA attributes
Section titled “ARIA attributes”| Attribute | Element | Value |
|---|---|---|
aria-label |
host | the label option |
aria-label |
slide | ‘N of M’ (plus the slide label) |
aria-live |
viewport | off while rotating automatically; polite otherwise |
aria-current |
current picker button | true |
aria-label |
pause button | ‘Stop automatic slide show’ or ‘Start automatic slide show’ |
inert |
inactive slides | present (not focusable, not read) |
Focus inside the carousel (or hovering it) pauses rotation; moving slides never moves focus.
WCAG 2.2 success criteria addressed
Section titled “WCAG 2.2 success criteria addressed”| Criterion | Level | Note |
|---|---|---|
| 1.3.1 Info and Relationships | A | |
| 2.1.1 Keyboard | A | |
| 2.2.2 Pause, Stop, Hide | A | |
| 2.3.3 Animation from Interactions | AAA | |
| 2.4.3 Focus Order | A | |
| 2.5.8 Target Size (Minimum) | AA | |
| 4.1.2 Name, Role, Value | A | |
| 4.1.3 Status Messages | AA |
Automated test results: Accessibility and compliance.
Notes and known caveats
Section titled “Notes and known caveats”- Autoplay is off by default; when on, the pause button is the first element (WCAG 2.2.2), and users who prefer reduced motion start paused.
- Picker dots keep a 24px target and the current one is filled, not only recolored.
- Manual screen-reader verification (NVDA, JAWS, VoiceOver) is pending.
Behavior
Section titled “Behavior”States
Section titled “States”First, middle, or last slide; loop; autoplay rotating or paused; a single slide (controls hidden).
State transitions
Section titled “State transitions”| From | Trigger | To |
|---|---|---|
| slide N | Next, a picker button, or a swipe | another slide; aui-change |
| rotating | hover, focus inside, or Pause | paused (hover and focus resume when they end; Pause until Play) |
| any | goTo() / update({ index }) |
the given slide, no event |
Accessibility notes
Section titled “Accessibility notes”- Moving content for more than five seconds needs a way to pause it (WCAG 2.2.2): the pause button is always there with autoplay.
- Users who prefer reduced motion start paused; the animation setting “none” disables rotation entirely.
- Changing slides never moves focus; announcements come from the live region.
- The e2e axe run covers three themes; manual screen-reader verification is pending.
Responsive behavior
Section titled “Responsive behavior”Slides take the full width; on touch screens a horizontal swipe moves between slides; the controls sit under the slides.
Right-to-left
Section titled “Right-to-left”The track and swipe directions mirror: the next slide comes from the left.
Theming
Section titled “Theming”The picker dot color is in the contrast gate; the current dot is filled, not only recolored. Forced colors use ButtonText and Highlight.
Global configuration
Section titled “Global configuration”configureAbsoluteUI({ components: { carousel: { showPicker: false } } });Component configuration
Section titled “Component configuration”Instance showPicker and locale override configuration; configuration changes re-render existing carousels.
Previous and next use the chevron-left and chevron-right icons (they follow the icon provider).
Security
Section titled “Security”String content is rendered as text; Node content is inserted as given.
Data handling
Section titled “Data handling”No persistence, network access, or telemetry.
Performance
Section titled “Performance”All slides stay in the DOM (inert when not shown); moving changes one CSS custom property and the inert flags.
Supported data scale
Section titled “Supported data scale”Up to 100 slides; intended for a handful.
Edge cases
Section titled “Edge cases”- Without
loop, previous is disabled on the first slide and next on the last. - With a single slide, the controls are hidden.
update({ slides })keeps the current index when it still exists, otherwise the last slide.
Errors
Section titled “Errors”| Code | Category | Cause |
|---|---|---|
CAROUSEL_OPTIONS |
configuration | Blank label, no slides or more than 100, slide content that is not a Node or string, an index out of range, or autoplay under 2000 ms. |
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION |
configuration | Invalid or unknown configuration. |
Invalid options throw before the host is modified; an invalid update() leaves the previous state intact.
Known limitations
Section titled “Known limitations”- One slide is shown at a time.
- Swiping is for touch and pen; mouse users use the buttons.
- Manual screen-reader verification is pending.
Unsupported scenarios
Section titled “Unsupported scenarios”- Several slides per view or free scrolling: use Scroll Area with a horizontal strip.
- Autoplay intervals shorter than 2 seconds.