Styles live in scss/components/_carousel.scss. Combine slide content (your markup) with .carousel controls; the live demos below show two compositions plus the control primitives.
Anatomy
| Part | Class | Role |
|---|---|---|
| Block | .carousel | Flex row: prev arrow + scroll bar + next arrow (gap 16px, max 640px) |
| Arrow | .carousel__arrow | 48×48px round button; --prev mirrors the icon |
| Scroll bar | .carousel__scrollbar | Track + thumb; use as slider when wired to slides |
| Doc widget | .pdoc-carousel-widget | Doc-only wrapper: viewport + aria-live status + controls |
| Slide | [data-carousel-slide] | One panel; toggle hidden + aria-hidden from JS |
Prerequisites
- PimentCSS installed, Installation.
- Icons,
ph-arrow-rightat 24px viaph()(Phosphor in this doc). - Slides, any HTML (image, text, cards); keep one visible slide at a time.
- Script, call
wireAllCarousels()after DOM ready (see interactive section).
Composed carousels (live)
Two widget patterns share the same .carousel controls. Use arrow keys on the carousel region or the scroll bar (slider). Status text updates in aria-live="polite".
Media + text
Split layout from min-width: 30rem: visual block + title and body copy. Decorative gradients use role="img" and a text alternative.
Text-only slides
Same controls and behavior without a media column. Useful for quotes, KPIs, or legal notices.
<div class="pdoc-carousel-widget" data-carousel-live="" role="region" aria-roledescription="carousel" aria-label="Featured topics" tabindex="-1">
<div class="pdoc-carousel-widget__viewport">
<article class="pdoc-carousel-widget__slide" data-carousel-slide="" role="group" aria-roledescription="slide" aria-label="1 of 3: Accessible forms">
<div class="pdoc-carousel-widget__media" role="img" aria-label="…"></div>
<div class="pdoc-carousel-widget__body">
<h3 class="pdoc-carousel-widget__title">Accessible forms</h3>
<p class="pdoc-carousel-widget__text">…</p>
</div>
</article>
</div>
<p data-carousel-status="" aria-live="polite">Slide 1 of 3: Accessible forms</p>
<div class="carousel pdoc-carousel-widget__controls">…</div>
</div>
Arrow primitives
48px circular buttons with a 2px action border. Doc-only .carousel__arrow--hover and .carousel__arrow--focus; production uses :hover and :focus-visible.
Scroll bar primitives
The scroll bar is a role="slider" when it reflects slide position (aria-valuenow, aria-valuemin, aria-valuemax). Default height is 2px; it grows to 4px on :hover. Use the interactive lab first, then compare the static state references below.
Static references (doc-only modifiers for focus/hover height previews):
Controls only
Use when slide content lives elsewhere (for example a full-width hero). Mark a decorative bar with aria-hidden="true".
JavaScript
Add data-carousel-live on .pdoc-carousel-widget (full carousel) or data-carousel-scrollbar-live on .pdoc-carousel-scrollbar-lab (scroll bar only). Call wireAllCarousels() after load.
import { wireAllCarousels } from './carousel-behavior';
document.addEventListener('DOMContentLoaded', () => wireAllCarousels());
// Full widget: .pdoc-carousel-widget[data-carousel-live] + [data-carousel-slide]
// Scroll bar lab: .pdoc-carousel-scrollbar-lab[data-carousel-scrollbar-live]
Class reference
| Class | Description |
|---|---|
.carousel | Control row (flex, gap 16px, max-width 640px) |
.carousel__arrow | 48×48px prev/next button |
.carousel__arrow--prev | Flips arrow icon (scaleX -1) |
.carousel__scrollbar | Track container (slider when wired) |
.carousel__scrollbar-thumb | Progress thumb; position with left |
.pdoc-carousel-widget | Doc layout: viewport + status + controls |
.pdoc-carousel-widget__slide | Single slide panel |
.pdoc-carousel-widget__media | Decorative visual block (doc demos) |
Customize (Sass)
-
Carousel sizing
Override max width, gaps, arrow size, and scroll bar metrics.@use "pimentcss-design-system" with ( $carousel-max-width: 40rem, $carousel-gap: 1rem, $carousel-arrow-size: 3rem, $carousel-scrollbar-thumb-width: 37.5% ); -
Rebuild CSS
Run after editing _carousel.scss.npm run build:css
Accessibility (RGAA / WCAG)
Carousel pattern
- Region,
role="region"+aria-roledescription="carousel"+ concisearia-label. - Slides,
role="group"+aria-roledescription="slide"; hide inactive slides withhiddenandaria-hidden="true". - Status,
aria-live="polite"text (slide x of y + title) updated on change. - Controls, labeled prev/next; disable at ends; scroll bar as
role="slider"when it reflects position. - Keyboard, Arrow Left/Right on the widget; Home/End on the slider; focus ring remains visible.
- Images, real content images need
alt; decorative blocks userole="img"+aria-label.