unscripted/ui

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-auto on the list, snap-center shrink-0 on the slides. That already scrolls, snaps, and works everywhere — swipe, trackpad, keyboard.
  • The dots and arrows come from the CSS Carousels spec: scroll-marker-group generates 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.

FeatureChromeEdgeFirefoxSafariWhen missing
CSS carousels (::scroll-marker / ::scroll-button)Limited availability135135The carousel still scrolls and snaps; dots and arrow buttons simply do not render.
CSS anchor positioningLimited availability12912914726The popover opens centered in the viewport (the top-layer default) instead of attached to its trigger.