Carousel
<caos-carousel>
a run of pictures shown one at a time, moved by hand or on a timer, that holds still for a reader who asked for less motion
May be placed on an app’s home page and a page inside an app.
Inputs
Section titled “Inputs”| Name | Attribute | Description | Type | Default | Required |
|---|---|---|---|---|---|
images |
property only | The images, as { src, alt, heading?, description?, href? } objects, in the order they are shown. src is the picture and alt is what it shows for somebody who cannot see it — an empty alt marks a picture that carries no meaning of its own. A heading and a description are drawn over the picture when they are given, and an href makes the whole slide a link. An entry with no src is dropped. | json | none declared | Optional |
autoplay |
autoplay, markup only |
Moves to the next image on a timer. Off unless set, and it never starts for a reader whose system asks for reduced motion, however this is set. The timer runs only while the carousel is on the page and there is more than one image to move between. | boolean | false | Optional |
interval |
interval, markup only |
How long each image holds before autoplay moves on, in milliseconds. Only read when autoplay is set. A value that is not a positive number leaves the carousel still rather than moving at some invented speed. | number | 5000 | Optional |
noPauseOnHover |
no-pause-on-hover, markup only |
Keeps autoplay running while a reader is engaged. Left unset, pointing at the carousel or moving focus into it stops the timer, and leaving starts it again, because a gallery that keeps moving under somebody reading it is the complaint this exists to answer. Declared as a negative, like noBorder and noIcon, because a page writes a yes/no as present-or-absent and a positive input that was on by default would have no reachable way to turn it off. | boolean | false | Optional |
label |
label, markup only |
What a screen reader calls this carousel, for a page holding more than one. Left unset it is announced as “Carousel”, which is enough when there is only the one. | text | none declared | Optional |
Events
Section titled “Events”| Name | When it fires | What it carries |
|---|---|---|
caos-carousel-change |
The image shown has changed — a previous or next press, an arrow key, a dot, autoplay moving on, or a goTo call. Not raised when the carousel is first drawn, and not raised when a move lands on the image already shown. | { index, count } — the image now shown, counting from zero, and how many there are. |
Not documented yet — this piece has not said.
Styling hooks
Section titled “Styling hooks”| Design token | What it controls |
|---|---|
--caos-color-surface |
The ground behind a picture that has not loaded, and the caption band. |
--caos-color-surface-2 |
The viewport behind the images. |
--caos-color-border |
The edge of the previous and next controls and of a dot. |
--caos-color-text |
The heading on a slide and the glyph on a control. |
--caos-color-text-muted |
The description under a heading. |
--caos-color-accent |
The dot marking the image being shown. |
--caos-font |
The typeface of the headings and descriptions. |
--caos-space-1 |
The padding inside a previous or next control. |
--caos-space-2 |
The gap between the viewport and the controls, and between the dots. |
--caos-space-3 |
The padding inside the caption band. |
--caos-radius |
The corners of the viewport. |
--caos-radius-pill |
The shape of the previous and next controls and of a dot. |
--caos-state-hover-bg |
A previous or next control under the pointer. |
--caos-focus-ring |
The ring drawn on a control reached by keyboard. |
--caos-duration-base |
How long one image takes to give way to the next. |
--caos-ease-standard |
The curve of that change. |
Methods
Section titled “Methods”| Name | Description | Arguments |
|---|---|---|
next() |
Move forward one image, wrapping from the last to the first. Returns false when nothing changed. | takes none |
previous() |
Move back one image, wrapping from the first to the last. Returns false when nothing changed. | takes none |
goTo() |
Show a particular image. Returns false when nothing changed — the index is outside the list, or it is the image already shown. | index: number |
play() |
Start the autoplay timer, as setting the attribute does. It does nothing for a reader who has asked for reduced motion, which is the one thing no caller can override. | takes none |
pause() |
Stop the autoplay timer, leaving the image that is showing on screen. | takes none |
Readable state
Section titled “Readable state”| Name | Type | What it tells you |
|---|---|---|
index |
number | The image shown now, counting from zero. |
count |
number | How many images the carousel is holding. |
playing |
boolean | Whether the autoplay timer is running now. False while it is paused for a hover, for focus, or for a reduced-motion preference, so it answers “is this moving” rather than “was it asked to”. |
Styling parts
Section titled “Styling parts”| Part | Which piece of it | When it is there |
|---|---|---|
::part(carousel) |
the whole gallery, viewport and controls together | Always |
::part(viewport) |
the window the images are shown in | Always |
::part(slide) |
one image and its caption | Always |
::part(image) |
the picture itself | Always |
::part(caption) |
the band over a picture holding its heading and description | the image carries a heading or a description |
::part(heading) |
the line of display text on a slide | the image carries a heading |
::part(description) |
the sentence under a heading | the image carries a description |
::part(controls) |
the row holding the previous and next controls and the dots | Always |
::part(previous) |
the control that goes back one image | Always |
::part(next) |
the control that goes forward one image | Always |
::part(dots) |
the run of marks, one per image | Always |
::part(dot) |
one mark, which moves to the image it names when pressed | Always |
When to use it
Section titled “When to use it”A short run of pictures that lead a page — four or five, each worth a moment on its own, where a reader is invited rather than asked to compare. If somebody needs to see them together, or to find a particular one, a grid is the honest answer: a carousel hides everything except the slide showing.
What to use instead
Section titled “What to use instead”- CardGrid — The reader needs to see the set at once and compare it, or to pick a particular one out of it.
- TabStrip — There are a few named faces of one subject and the reader chooses between them, with nothing moving on its own.
Accessibility
Section titled “Accessibility”The carousel is a region announced as a carousel, and each slide is a group labelled with its position, so a screen reader says which of how many is showing. The slides not showing are hidden rather than merely out of sight, so they are out of the tab order and the accessibility tree and a reader never tabs into a picture nobody can see. Previous and next are real buttons, each dot is a button naming the image it goes to, and Arrow Left and Arrow Right move between images while Home and End go to the first and the last. A polite status region reports the new position on a move somebody made, and is silenced while autoplay is running so a reader is not interrupted every few seconds by motion they did not ask for. Reduced motion is honoured in behaviour and not only in paint: autoplay does not start, the gallery rests on the first image, and moving by hand still works. What is left to the author: an alt for every picture that carries meaning, and an empty one for every picture that does not.
Examples
Section titled “Examples”A run of pictures
Section titled “A run of pictures”The ordinary case: three pictures, moved by the controls or the arrow keys. Nothing moves on its own, because autoplay was not asked for.
{ "id": "example", "section": "A run of pictures", "columns": 1, "items": [ { "id": "carousel_1", "type": "component", "key": "carousel", "inputs": { "label": "Platform highlights", "images": [ { "src": "https://images.example.com/workspace.jpg", "alt": "A workspace with several records open side by side" }, { "src": "https://images.example.com/builder.jpg", "alt": "A page being assembled from the component palette" }, { "src": "https://images.example.com/community.jpg", "alt": "People at a community meet-up around a long table" } ] } } ]}<caos-carousel id="carousel1" label="Platform highlights"></caos-carousel>// What an attribute cannot hold, set as a property — the same values the preview is drawn with.const carousel1 = document.getElementById('carousel1');carousel1.images = [ { "src": "https://images.example.com/workspace.jpg", "alt": "A workspace with several records open side by side" }, { "src": "https://images.example.com/builder.jpg", "alt": "A page being assembled from the component palette" }, { "src": "https://images.example.com/community.jpg", "alt": "People at a community meet-up around a long table" }];Moving on a timer
Section titled “Moving on a timer”Autoplay set with a four-second hold. Pointing at it or moving focus into it stops the timer, and leaving starts it again.
{ "id": "example", "section": "Moving on a timer", "columns": 1, "items": [ { "id": "carousel_1", "type": "component", "key": "carousel", "inputs": { "label": "What the platform does", "autoplay": true, "interval": 4000, "images": [ { "src": "https://images.example.com/workspace.jpg", "alt": "A workspace with several records open side by side" }, { "src": "https://images.example.com/builder.jpg", "alt": "A page being assembled from the component palette" }, { "src": "https://images.example.com/academy.jpg", "alt": "A lesson page open at a short exercise" } ] } } ]}<caos-carousel id="carousel1" label="What the platform does" autoplay interval="4000"></caos-carousel>// What an attribute cannot hold, set as a property — the same values the preview is drawn with.const carousel1 = document.getElementById('carousel1');carousel1.images = [ { "src": "https://images.example.com/workspace.jpg", "alt": "A workspace with several records open side by side" }, { "src": "https://images.example.com/builder.jpg", "alt": "A page being assembled from the component palette" }, { "src": "https://images.example.com/academy.jpg", "alt": "A lesson page open at a short exercise" }];The same gallery, reduced motion
Section titled “The same gallery, reduced motion”The same element under a reduced-motion preference — the timer never starts and the gallery rests on the first picture. Turn the setting on and this is what the example above becomes.
{ "id": "example", "section": "The same gallery, reduced motion", "columns": 1, "items": [ { "id": "carousel_1", "type": "component", "key": "carousel", "inputs": { "label": "What the platform does", "autoplay": true, "interval": 4000, "images": [ { "src": "https://images.example.com/workspace.jpg", "alt": "A workspace with several records open side by side" }, { "src": "https://images.example.com/builder.jpg", "alt": "A page being assembled from the component palette" }, { "src": "https://images.example.com/academy.jpg", "alt": "A lesson page open at a short exercise" } ] } } ]}<caos-carousel id="carousel1" label="What the platform does" autoplay interval="4000"></caos-carousel>// What an attribute cannot hold, set as a property — the same values the preview is drawn with.const carousel1 = document.getElementById('carousel1');carousel1.images = [ { "src": "https://images.example.com/workspace.jpg", "alt": "A workspace with several records open side by side" }, { "src": "https://images.example.com/builder.jpg", "alt": "A page being assembled from the component palette" }, { "src": "https://images.example.com/academy.jpg", "alt": "A lesson page open at a short exercise" }];Headings, descriptions and links
Section titled “Headings, descriptions and links”Each picture carrying a heading, a sentence under it, and a link, so a slide leads somewhere instead of only being looked at.
{ "id": "example", "section": "Headings, descriptions and links", "columns": 1, "items": [ { "id": "carousel_1", "type": "component", "key": "carousel", "inputs": { "label": "Where to start", "images": [ { "src": "https://images.example.com/academy.jpg", "alt": "A lesson page open at a short exercise", "heading": "Learn the platform", "description": "Short lessons that build one working app end to end.", "href": "/academy" }, { "src": "https://images.example.com/community.jpg", "alt": "People at a community meet-up around a long table", "heading": "Meet the community", "description": "Questions answered by the people who build on this every day.", "href": "/community" }, { "src": "https://images.example.com/careers.jpg", "alt": "Two colleagues talking at a desk by a window", "heading": "Work with us", "description": "The roles open right now, and what each team is building.", "href": "/careers" } ] } } ]}<caos-carousel id="carousel1" label="Where to start"></caos-carousel>// What an attribute cannot hold, set as a property — the same values the preview is drawn with.const carousel1 = document.getElementById('carousel1');carousel1.images = [ { "src": "https://images.example.com/academy.jpg", "alt": "A lesson page open at a short exercise", "heading": "Learn the platform", "description": "Short lessons that build one working app end to end.", "href": "/academy" }, { "src": "https://images.example.com/community.jpg", "alt": "People at a community meet-up around a long table", "heading": "Meet the community", "description": "Questions answered by the people who build on this every day.", "href": "/community" }, { "src": "https://images.example.com/careers.jpg", "alt": "Two colleagues talking at a desk by a window", "heading": "Work with us", "description": "The roles open right now, and what each team is building.", "href": "/careers" }];