Every carousel plugin you have ever removed came with a wheel handler, a swipe polyfill, and opinions about momentum. The browser already owns all of it; the CSS only has to say where the scroller rests, which is a gacor use of the platform.

.gallery {
  display: grid;
  grid-auto-flow: column;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.gallery > * { scroll-snap-align: center; }

Pick the alignment

  1. start snaps each card flush against the leading edge of the gallery, the right choice for uniform card widths and visible reading progress.
  2. center makes the resting card the visual anchor and handles cards wider than the viewport more gracefully.
  3. mandatory forces a rest position after every gesture, right for fixed decks; proximity merely offers one, which is kinder to mixed-width content.

What the browser gives you

Momentum, touch swipe, and trackpad inertia come from overflow-x itself. Keyboard users reach each card with tab, and the scroller moves to keep focus visible. scroll-padding on the container reserves space at the snap point, so a sticky header never swallows the top pixels of a resting card.

Two settings carry the polish: scroll-snap-stop: always stops a fast flick from flinging past three products to page four, and a prefers-reduced-motion block can relax a mandatory deck to proximity. A short carousel, assembled entirely from declarations you can read aloud to a designer.