Carousel JavaScript
Progressively enhance CSS scroll-snap carousels with controls, looping, and touch gestures.
Initialize controls, looping, and swipe behavior
This preview runs the same next/previous state model documented below.
<link rel="stylesheet" href="/components/carousel.css" />
<carousel loop>...</carousel>
<script type="module" src="/carousel.js"></script> More examples
Each example introduces a different part of the shipped API.
Initialization adds state, not structure
The script updates inert slides, control availability, and the initialized marker on existing semantic markup.
import { initializeCarousels } from "css-tags/carousel.js";
initializeCarousels(document);
// Re-run for newly inserted application fragments. data-carousel-initialized="true"aria-hidden="true" + inertdisabled previous/next controlsThe CSS carousel works as a horizontally scrollable, snap-aligned collection without JavaScript. Import carousel.js when you also want previous/next controls, looping, and swipe gestures.
Setup
<link rel="stylesheet" href="/components/carousel.css" />
<section data-carousel aria-label="Featured articles"> <div data-carousel-slides> <article data-carousel-item>First article</article> <article data-carousel-item>Second article</article> <article data-carousel-item>Third article</article> </div>
<button type="button" data-carousel-trigger direction="prev" aria-label="Previous article">‹</button> <button type="button" data-carousel-trigger direction="next" aria-label="Next article">›</button></section>
<script type="module" src="/carousel.js"></script>Use native buttons for the triggers. They provide keyboard behavior and disabled semantics without recreating either feature in JavaScript.
Supported hosts
The initializer recognizes the same three host forms as the CSS:
- Carousel:
carousel,[data-carousel],.carousel - Slides:
[data-carousel-slides],.carousel-slides - Item:
carousel-item,[data-carousel-item],.carousel-item - Trigger:
carousel-trigger,[data-carousel-trigger],.carousel-trigger
Add loop to the carousel host to wrap from the last slide to the first. Without it, the script disables the previous or next button at the corresponding edge.
Programmatic initialization
The module initializes document carousels automatically. It also exports the initializer for content added later or rendered inside another root:
import { initializeCarousels } from "/carousel.js";
initializeCarousels(document.querySelector("#new-content"));Calling the initializer again is safe; initialized carousels are skipped.
Progressive enhancement
Keep the slides container horizontally scrollable in the CSS fallback. JavaScript changes the slide widths and transform only after it finds a valid host, slides container, and at least one item. Touch gestures use passive listeners, and the CSS removes transition animation when the user prefers reduced motion.