Carousel
Try it yourself
Catalog sizes control compact card geometry. Editorial cards use content spans and keep descriptions visible. The code below follows your selections.
<script lang="ts">
import { CarouselSection } from '@page-sections/svelte';
const list = [
{
"id": "coast",
"title": "Notes from the coast",
"eyebrow": "Field notes",
"description": "Make space for stories, observations and a slower way of seeing.",
"href": "#playground",
"image": {
"src": "../../../coast.svg",
"alt": "Sandstone cliffs beside the sea"
}
},
{
"id": "hills",
"title": "A different perspective",
"description": "Cards without an eyebrow still align with their neighbours.",
"href": "#playground",
"image": {
"src": "../../../landscape.svg",
"alt": "Layers of green hills"
}
},
{
"id": "journey",
"title": "Small beginnings, longer journeys",
"eyebrow": "Experiments",
"description": "Try a different image ratio and notice that the text keeps its own space.",
"href": "#playground",
"image": {
"src": "../../../coast.svg",
"alt": "A sunlit coastline"
}
},
{
"id": "more",
"title": "Room to grow",
"eyebrow": "Ideas",
"description": "Explore equal heights and responsive columns with content of different lengths.",
"href": "#playground",
"image": {
"src": "../../../landscape.svg",
"alt": "A landscape of hills"
}
}
];
</script>
<CarouselSection
section={{ id: 'collection', title: 'Collection' }}
{list}
cardSize="m"
cardTone="muted"
cardVariant="catalog"
mediaAspect="3/2"
mediaFit="contain"
textAlign="start"
/> # CarouselSection
A native horizontal collection using the same card sizes as CardGridSection. It is progressively enhanced with previous/next buttons and selection callbacks; it does not implement Spatial Elements' virtual scrolling, camera or 3D selection mechanics.
<script lang="ts">
import { CarouselSection, type CardItem } from '@page-sections/svelte';
const list: CardItem[] = [
{ id: 'one', title: 'First', href: '/one' },
{ id: 'two', title: 'Second', href: '/two' }
];
</script>
<CarouselSection
section={{ id: 'browse', title: 'Browse', headline: 'Explore the collection' }}
{list}
cardSize="m"
/> Card surfaces accept cardTone="standard" (default) or "muted", also through JSON section data. They use the same palette as
panels and are independent of the section background.
Props
Generic over T extends CardItem. Required section: SectionDefinition and list: T[]. Optional cardSize (m), cardVariant (catalog), mediaAspect (3/2; also 4/3 or 1/1), mediaFit (contain for catalog, cover for editorial), textAlign (start), controls (true), previousLabel (Previous cards), nextLabel (Next cards), media(item), itemContent(item), oncardready(parts), initialItemKey and onselectionchange(key).
initialItemKey is applied once after mount, matching itemKey ?? id.
onselectionchange reports the occurrence nearest the leading edge after a native scrollend;
duplicate content identities require unique occurrence keys. Initial placement and callback
are enhancements; SSR starts at the first item. oncardready has the same lifecycle as Card.
Layout and interaction
Each slide takes the canonical S/M/L column span, with the same container width, outer gutters and gap as CardGridSection. Slides share equal heights. Catalog cards use the selected media ratio plus independent title space and a collection-wide eyebrow row. S/M titles have two lines, L three; S hides eyebrows. Contained media has an 8px inset; cover fills the frame. Editorial mode grows with content. The previous arbitrary pixel width caps and ps-carousel-card-width override were removed.
The focusable native region supports touch, wheel/trackpad and keyboard scrolling without JavaScript. CSS scroll snapping aligns cards to the leading edge. Controls appear only after mount, when enabled and the collection has more than one item. Each moves by 85% of the track; reduced motion disables smooth scrolling. RTL reverses scrolling direction and selection-edge calculations.
Accessibility and SSR
Supply translated region and button labels. The component is a scrollable collection, not a live slideshow; there is no autoplay or live announcement. Cards inherit their heading level and keep native links in server HTML.
Related: CardGridSection, Core API, shared layout reference.