Usage

When to reach for Carousel, what it needs to show at all, and how to keep it usable.

When to use

Use a Carousel when the panels are interchangeable, each is worth the whole space, and the reader loses nothing by seeing one at a time: a hero rotation, a photo gallery, a set of quotes. Think twice, since whatever is on slide 3 is, for most readers, not on the page at all.
  • A scrollable row when the reader should see that there is more. A row cut off at the edge invites a scroll.
  • Tabs when the panels have names. A dot cannot carry a name.
  • A Grid or Masonry when the reader should compare everything at once.
Wrap each slide in a div. Every direct child is one slide. A bare string, or a fragment with two nodes, does not split into two slides.
Give every slide a height. Slides have no height of their own, so a deck of text-only slides collapses.

Autoplay, and the pause it owes the reader

autoplay is off by default and takes a boolean or an object. { dotDuration: true } fills the active dot as a progress bar, which tells the reader how long the slide has left. autoplaySpeed is the interval in milliseconds, 3000 by default.
  • Anything that moves on its own for more than five seconds needs a way to stop it. It pauses on hover but not on focus, so turn on pauseOnFocus and add a pause button that uses the ref.
  • Autoplay ignores reduced motion. Carousel does not check prefers-reduced-motion, and a motion-safe: class cannot stop it. Read the setting yourself and pass autoplay={false}.
  • 3000 is too fast for slides with text. Give readers 7 to 10 seconds, and the pause control still.
  • Do not autoplay two carousels on one page.

Dots, and where they sit

dots is on by default and also takes { className } to style the dot row.
  • dotPlacement start or end makes it vertical. Pass vertical={false} to keep side dots on a horizontal carousel. top and bottom stay horizontal.
  • dotPosition is deprecated and warns. Use start for left and end for right.
  • Past about eight slides, dots are too many to aim at. Cut the deck or add paging that names the slides.
  • dots={false} leaves no visible position. Do it only when something else shows where the reader is.

Arrows, and the color problem behind them

The arrows are always white. arrows is off by default, and when on it draws white arrows whatever the theme. The dots use the background color at low opacity. On a light slide, give the slide a dark background or recolor the dots.
  • Turn arrows on for desktop readers, who otherwise have only the dots to aim at.
  • To recolor the dots, style .slick-dots li button and, for the active dot, li.slick-active::after. The button's own ::after is its invisible hit area.
  • Check the deck against its lightest slide.
  • prevArrow and nextArrow take your own element, which has to spread the onClick and className it receives. A custom arrow loses the default label, so give it an aria-label.

The transition, and whether it loops

  • effect is scrollx by default, or fade. Keep faded slides one size. effect="fade" cross-fades in place, so slides of different sizes jump at each change. speed is the duration in milliseconds, 500 by default.
  • infinite is on by default, and it copies the slides at both ends so the loop wraps smoothly. Anything inside a slide then exists more than once: an id, a form control, an impression event. A fade carousel makes no copies.
  • infinite={false} gives the deck a real first and last slide. The arrow at each end disappears rather than dimming, so do not rely on it keeping its space.
  • A sequence with a beginning and an end should not loop.

How many slides are visible

Many props come from react-slick. slidesToShow, slidesToScroll, centerMode, centerPadding, variableWidth and responsive pass through to react-slick, and its docs cover them.
  • slidesToShow and slidesToScroll both default to 1. Keep them equal unless you want neighbors peeking in.
  • responsive follows the window. Its breakpoints are react-slick's own numbers and watch the window width, not the container, so they do not line up with your Tailwind breakpoints.
  • Once several slides show at once, check whether a scrollable row would do the job better.

beforeChange and afterChange

beforeChange(current, next) fires as a move starts, and afterChange(current) when it lands.
  • Use beforeChange for work that should start with the move, like preloading the next image.
  • Use afterChange for what reflects where the deck is: an analytics event, a synced thumbnail row, a live region announcing the slide.
  • Neither makes the deck controlled. There is no value, and initialSlide only sets where it starts. Move it with the ref.

Driving it from a ref

Drive it from a ref. The ref has goTo, next, prev and autoPlay. To sync two carousels, call goTo on one from the other's afterChange. The ref cannot be passed to asNavFor.
  • goTo(index, dontAnimate) jumps to a slide. next() and prev() do what the arrows do.
  • Make your own controls real buttons with names. An arrow glyph in a div is neither.