Carousel
Scroll snap does the carousel; the CSS Carousels spec adds dots and arrow buttons the browser generates, wires up, and keeps accessible.
CSS carouselsanchor positioning
How it works
- The base is utilities only:
snap-x snap-mandatory overflow-x-autoon the list,snap-center shrink-0on the slides. That already scrolls, snaps, and works everywhere — swipe, trackpad, keyboard. - The dots and arrows come from the CSS Carousels spec:
scroll-marker-groupgenerates a dot per slide (::scroll-marker, current one via:target-current), and::scroll-button(left/right)are real, focusable, auto-disabling buttons the browser creates and operates. The arrows are pinned to the carousel’s edges with anchor positioning.
The one required-CSS block in the library
Generated pseudo-elements need content and their own layout — there’s no utility syntax for
“create a button per scroll target”. This is the only component where copy-paste means
“markup + a CSS block”, and the block is optional: skip it and you keep a working scroll-snap
carousel.
Browser support
Minimum stable version per engine, resolved at build time from MDN's browser-compat-data; Baseline status from the official web-features dataset. Everything degrades gracefully — the “when missing” column is the actual behavior, not a broken page.
| Feature | Chrome | Edge | Firefox | Safari | When missing |
|---|---|---|---|---|---|
| CSS carousels (::scroll-marker / ::scroll-button)Limited availability | 135 | 135 | ✕ | ✕ | The carousel still scrolls and snaps; dots and arrow buttons simply do not render. |
| CSS anchor positioningLimited availability | 129 | 129 | 147 | 26 | The popover opens centered in the viewport (the top-layer default) instead of attached to its trigger. |