HyCarousel
Usage examples on this page are written for Lit / plain HTML (
<hy-carousel>). The same component ships asHyCarouselin@whitespaceux/harmony-react(native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.
A native-first carousel built on CSS scroll-snap. Each direct child of <hy-carousel> is treated as a slide. The component renders a Lit baseline navigation and pagination UI so it works cross-browser, and progressively enhances to ::scroll-button / ::scroll-marker pseudo-elements where supported (Chromium 135+, via @supports in the styles).
Rendering model
- Viewport is a flex scrollport with
scroll-snap-type. Slides are direct children of the host, slotted into the shadow-DOM scrollport. - Active slide tracking uses
IntersectionObserverrooted on the viewport withthreshold: 0.5. - Keyboard works from the viewport (
tabindex="0"): Arrow keys, Home/End, PageUp/PageDown. - Autoplay pauses on pointer enter, focus, and hidden tabs, and is disabled entirely when
prefers-reduced-motion: reducematches.
When to use
- A few items people browse one view at a time where space is short: product photos, featured articles.
Do
- Show where people are in the set, with
pagination. - Leave
autoplayoff unless the slides are decorative.
When not to use
- Content people must see, or one item that matters more than the others: give it its own section on the page.
- Items people compare, or more than about five: a grid of
hy-cardso all are visible at once. - A scrolling strip with no paging: a plain container with
overflow-x: auto. - Steps people complete in order:
hy-stepper. - Named panels people choose between:
hy-tab-group.
Accessibility: your part
- Set
navigationandpaginationso the slides can be reached without swiping and the current position shows. - Leave
autoplayoff; slides that move on their own interrupt reading and screen-reader use. - Make each slide understandable on its own when it is announced, with alt text on its images.
Examples
Basic horizontal carousel
<hy-carousel navigation pagination label="Featured products">
<article>Slide 1</article>
<article>Slide 2</article>
<article>Slide 3</article>
</hy-carousel>API
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
navigation | navigation | boolean | false | Render baseline Previous/Next buttons inside the viewport. |
pagination | pagination | boolean | false | Render baseline pagination markers below the viewport. |
orientation | orientation | 'horizontal' | 'vertical' | 'horizontal' | Scroll axis. |
snap | snap | 'mandatory' | 'proximity' | 'mandatory' | mandatory snaps the scrollport strictly; proximity enables a peek. |
autoplay | autoplay | boolean | false | Advance the active slide on a timer. Disabled automatically when prefers-reduced-motion. |
autoplayInterval | autoplay-interval | number | 5000 | Milliseconds between autoplay advances. |
label | label | string | '' | Accessible label for the carousel region. Required for a meaningful a11y label. |
strings | — | Partial<CarouselStrings> | {} | The built-in strings, merged over DEFAULT_CAROUSEL_STRINGS — set only the keys you translate. Use for internationalization. |
Events
| Event | Detail | Description |
|---|---|---|
change | — | Fires when the active slide changes (scroll settles past 50% threshold). Detail: { index, slide }. |
input | — | Fires during drag when the active slide crosses the threshold. May fire multiple times per gesture. Detail: { index, slide }. |
Slots
| Slot | Description |
|---|---|
default | Slides — each direct child is treated as one slide. |
CSS Parts
| Part | Description |
|---|---|
base | The carousel's outer wrapper. |
viewport | The scrollport element that overflows. |
navigation | The navigation button group (baseline path). |
navigation-prev | The previous button. |
navigation-next | The next button. |
pagination | The pagination marker group. |
marker | An individual pagination marker. |
CSS Custom Properties
The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.
| Property | Default | Description |
|---|---|---|
--hy-carousel-padding-layout-none | var(--hy-padding-layout-none) | Inner padding of the scrollport. |
--hy-carousel-gap-container-md | var(--hy-gap-container-md) | Gap between slides. |
--hy-carousel-ornament-bullet | var(--hy-ornament-bullet) | Marker dot size. |
--hy-carousel-marker-border-subtle-rest | var(--hy-border-subtle-rest) | Marker rest color. |
--hy-carousel-background-brand-indicator-rest | var(--hy-background-brand-indicator-rest) | Active marker color. |
--hy-carousel-background-surface-base | var(--hy-background-surface-base) | Nav button background. |
--hy-carousel-foreground-default-rest | var(--hy-foreground-default-rest) | Nav button foreground. |
--hy-carousel-aspect-ratio | auto | Aspect ratio of the viewport. Default: auto. |
--hy-carousel-motion-transition-hover-duration | var(--hy-motion-transition-hover-duration) | Transition duration for hover and focus state feedback on controls |
--hy-carousel-motion-transition-hover-easing | var(--hy-motion-transition-hover-easing) | Transition easing for hover and focus state feedback on controls |
Methods
goTo()
Scrolls to the slide at the given index.
next()
Advances to the next slide, stopping at the end.
prev()
Goes to the previous slide, stopping at the start.