Carousel
A scroll-snap track of slides with prev/next controls, dots, keyboard, and opt-in autoplay.
Live demo
Carousel lays its slotted children out as a horizontal scroll-snap track: each child is a slide, and the browser's own scrolling does the paging, so the track is swipeable and keyboard-scrollable with no JavaScript at all. When the runtime is present it grows a control bar, prev and next buttons (drawn with the chevron icons), a row of pagination dots that track and drive the active slide, and arrow-key and Home/End navigation, all wired over the same native scroll.
An opt-in autoplay advances the track on an interval, pausing on hover and focus and standing still entirely under prefers-reduced-motion; loop wraps the ends seamlessly, scrolling into an inert clone of the far slide and then silently snapping to the real one so the wrap never rewinds. The transition prop swaps the paging model: slide keeps the scroll-snap track, while fade, scale, and flip stack the slides and cross-fade the active one, so a testimonial or hero rotator can dissolve rather than slide. It is content-agnostic: the slides can be Images, Cards, or any markup, and it exposes itself as a labelled carousel region with each slide named for assistive tech.
When to use
How this component composes with the rest of the set.
Props
9 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Anatomy
The named parts that make up the component, with their selectors.
track
The horizontal scroll-snap container that holds and pages the slides.
nav
The prev/next buttons.
dots
The pagination dots; the active one takes the accent. When the theme's --selection-cue resolves to marker, the active dot also elongates into a pill so the current slide reads by shape, not color alone.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xtyle-default register
(derive(xtyleDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--accent
--bg-1
--bg-2
--bg-3
--border-thick
--border-thin
--duration-fast
--duration-slow
--ease-emphasized
--ease-standard
--elevation-2
--fg-1
--fg-2
--fg-3
--line-2
--radius-full
--ring
--selection-cue
--space-2
--space-3
--space-6
--surface-overlay
--surface-overlay-border
Slots
The slides. Each direct child becomes one slide in the track (an Image, a Card, or any markup).
Accessibility
Code
Image gallery
A few slides in a scroll-snap track with prev/next controls and dots.
<xtyle-carousel label="Product photos">
<img src="/a.jpg" alt="Front" />
<img src="/b.jpg" alt="Side" />
<img src="/c.jpg" alt="Back" />
</xtyle-carousel>
<script lang="ts">
import { Carousel } from "@xtyle/svelte";
</script>
<Carousel label="Product photos">
<img src="/a.jpg" alt="Front" />
<img src="/b.jpg" alt="Side" />
</Carousel>
---
import Carousel from "@xtyle/astro/Carousel.astro";
import Image from "@xtyle/astro/Image.astro";
---
<Carousel label="Gallery">
<Image src="/a.jpg" alt="First" ratio="16/9" />
<Image src="/b.jpg" alt="Second" ratio="16/9" />
</Carousel>
Autoplay and loop
An auto-advancing, looping track that pauses on hover or focus.
<xtyle-carousel label="Highlights" autoplay interval="4000" loop>
<div>Slide one</div>
<div>Slide two</div>
<div>Slide three</div>
</xtyle-carousel>
<script lang="ts">
import { Carousel } from "@xtyle/svelte";
</script>
<Carousel label="Highlights" autoplay interval={4000} loop>
<div>Slide one</div>
<div>Slide two</div>
</Carousel>
---
import Carousel from "@xtyle/astro/Carousel.astro";
---
<Carousel label="Highlights" autoplay interval={4000} loop>
<div>Slide one</div>
<div>Slide two</div>
</Carousel>
Fade transition
A stacked cross-fade instead of a sliding track, for a testimonial or hero rotator.
<xtyle-carousel label="Featured" transition="fade" autoplay loop>
<div>First</div>
<div>Second</div>
<div>Third</div>
</xtyle-carousel>
<Carousel label="Featured" transition="fade" autoplay loop>
<div>First</div>
<div>Second</div>
<div>Third</div>
</Carousel>
<Carousel label="Featured" transition="fade" autoplay loop>
<div>First</div>
<div>Second</div>
<div>Third</div>
</Carousel>