Carousel replacements: controls, motion and semantics

Dataset Last tested 24 October 2026

Choose a carousel by the controls and motion behaviour your page needs, then inspect the configuration behind each result. This index compares twenty implementations without scores or rankings; an autoplay carousel should stop when keyboard focus enters and leave restarting to the reader.1

Start with the controls you need

Eighteen rows use libraries or web components; two use related original CSS scroll-snap patterns. The CSS rows share a browser platform and are not independent products. Every record identifies the version, source URL, licence, package-file hashes and exact fixture. Use the roster to compare the listed configurations.

Each fixture contains three panels with original text and focus targets. Some packages generate controls; others use author-supplied markup or API adapters. Buttons labelled Harness are original adapters. The row notes distinguish these from controls supplied by a package, so a working adapter is not mistaken for a built-in interface.

NameVersionFocus pauseMotionSR slideKeyboardSwipeStopNo JS
Swiper14.3.0YN*–YY*partial–
Splide4.1.4YY*–YY*partial–
Embla Carousel + Autoplay8.6.0YN*–YY*partial–
Keen Slider6.8.6–N*–YN*–partial
Glide.js3.7.1NN*–YY*partial–
Owl Carousel2.3.4NN*–YY*partial–
Slick2.0.0YN*–YY*partialpartial
Tiny Slider2.9.4NN*–Ypartial*partial–
Siema1.5.1–N*–YY*–partial
Glider.js1.7.10–N*–YY*––
Lory2.5.3–N*–YY*––
Bootstrap Carousel5.3.8Npartial*–YY*partialpartial
Materialize Carousel1.0.0–N*–YY*––
UIkit Slideshow3.25.27YN*–YY*partial–
Shoelace Carousel2.20.1Ypartial*–YY*partial–
Blaze Slider1.9.3NN*–YY*partial–
Swiffy Slider2.1.2NN*–YY*partial–
A11Y Slider0.4.22NN*–YY*Ypartial
CSS horizontal snap + anchor navigation1.0.0-original-pattern–partial*–partialY*–partial
CSS vertical snap + sequential anchors1.0.0-original-pattern–partial*–partialY*–partial

Y = observed; N = observed contradiction; partial = qualified; – = not tested; * = emulated.

NameAX slide live contentAX control names
SwiperNY
SplideYY
Embla Carousel + AutoplayNN
Keen SliderNN
Glide.jsNY
Owl CarouselNN
SlickNY
Tiny SliderYY
SiemaNN
Glider.jsNY
LoryNY
Bootstrap CarouselNY
Materialize CarouselNN
UIkit SlideshowNY
Shoelace CarouselNY
Blaze SliderNY
Swiffy SliderNY
A11Y SliderYY
CSS horizontal snap + anchor navigationNY
CSS vertical snap + sequential anchorsNY

Y = present in the accessibility tree; N = absent; – = not tested. These are not screen-reader results.

Read the labels before filtering

Y records the named behaviour, N records an observed contradiction, and partial records a limited or qualified result. – preserves an unanswered question. * marks a simulated input or preference. The motion field concerns prefers-reduced-motion, the media feature for a preference to reduce non-essential motion.2 Pointer events identify an input type; a touch label does not by itself identify physical hardware.3

Keyboard reachability means the controls could receive keyboard focus; it does not establish successful activation in both directions.

Read the separate accessibility-tree table independently of the seven behaviour columns. Current-slide live content requires a live-region property tied to slide content. Control names requires a name on every inspected component control; Harness controls are excluded. Neither column reports what a person heard through a screen reader.

Read intermediate slide events as well as the final slide number. A carousel can complete a cycle and finish where it started. The logs retain those transitions, focus events and activated controls so a matching endpoint cannot conceal continued motion. Changes to a fixture, package option or browser belong in a new dated record.

Follow a result back to its fixture

Use the demo to search names and filter exact labels. It embeds the comparison records, loads no carousel package and displays fixture paths as plain text. A filter selects saved records; it does not execute a carousel. The CSV and JSON carry the full notes and provenance.

METHOD.md lists every package version, file hash and test step, so any row can be reproduced from the published package versions. The tested package files are kept in a separate test harness and are not republished here.

Interpret file sizes and dependencies

The size field counts uncompressed bytes in selected, identifiable upstream minified JavaScript files. It stays empty, with a reason, when no qualifying distribution exists. No local minifier substitutes a smaller figure. This is a file-size record, not a measurement of compressed transfer, production bundles, speed or responsiveness.

Dependency counts describe declared direct runtime entries. Peer requirements and packages added by the fixture have their own fields. Zero direct dependencies does not mean no other code is present: stylesheets, plugins and embedded licence notices are recorded separately.

Use the slider replacement guide to work through control mapping, timers and teardown before choosing a package. Keep the required behaviour explicit, and retain a local reproduction of any mismatch rather than treating a comparison row as a production guarantee.

Our observation data is licensed under CC BY 4.0. The tested packages retain their own licences.

Not covered on this page

Sources

  1. WAI-ARIA Authoring Practices: Carousel pattern. Interaction and semantic guidance. Accessed 24 October 2026. ↩

  2. MDN: prefers-reduced-motion. Media preference reference. Accessed 24 October 2026. ↩

  3. MDN: Pointer events. Input-event reference. Accessed 24 October 2026. ↩

How we test: methodology. Found a mistake? Corrections.