← Visual Library / Carousels

Scroll-snap horizontal carousel

A native horizontal swipe gallery using CSS scroll-snap. Zero JS. Feels like a native iOS picker.

Carousels Built JS-free
Use when — you want to show a bunch of items where the user can swipe through them on phone (and scroll on desktop). Great for portfolio reels, listing thumbnails, product variants. Set flex-basis low enough that the user always sees a sliver of the next item — a strong visual cue that there's more.

Live demo

Villa Cala Vadella
Casa Sant Josep
Finca Es Cubells
Apartamento Marina
Estilo payés moderno
Swipe / scroll → 5 properties

How it works

Flex row with overflow-x: auto + scroll-snap-type: x mandatory on the parent and scroll-snap-align: center on each child. The browser handles the snap behavior natively. Set children to flex: 0 0 85% on phone so a sliver of the next item shows — that's the affordance that says "swipe me."

The code (HTML)

<div class="reel">
  <div class="slide-card">Villa 1</div>
  <div class="slide-card">Villa 2</div>
  <div class="slide-card">Villa 3</div>
</div>

The code (CSS — the key bits)

.reel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  gap: 12px;
  -webkit-overflow-scrolling: touch;
}
.slide-card {
  flex: 0 0 85%;          /* phone: show sliver of next */
  scroll-snap-align: center;
}
@media (min-width: 720px) {
  .slide-card { flex-basis: 42%; }  /* desktop: two cards visible */
}

Variants worth considering

Full-width slides — set flex-basis: 100% if you want one item per viewport. Pair with dot indicators below using radio inputs + :target for navigation (or accept "no nav" if pure swipe is enough).

Vertical scroll-snap on desktop — Peñaranda y Cobo uses this pattern: vertical scroll-snap reel on desktop, horizontal on phone. Different axis matches each device's natural gesture. See vault/Topics/web-patterns.md § Pattern 24 (Cinema reel).

Snap on the edge — change scroll-snap-align: center to start for a different feel. Center is more "carousel-y" — cards sit centered. Start is more "list-y" — items line up from the left.

Compatibility: scroll-snap supported in all modern browsers. · Code playbook cross-ref: vault/Topics/web-patterns.md § Pattern 24 (Cinema reel).