Horizontal Scroll Gallery

Pinned section where vertical scroll drives horizontal gallery position. Same pattern as Scroll-Linked Video Scrubber.

Component

1
2
3
4
5
6
7
8

Installation

pnpm dlx shadcn@latest add "https://pulkitxm.com/components/horizontal-scroll-gallery.json"

Usage

Import

Add the import.

import { useRef } from "react";
import { HorizontalScrollGallery } from "@/components/horizontal-scroll-gallery";

Use

Wrap gallery items. Pass scroller when inside a scroll container.

const containerRef = useRef<HTMLDivElement>(null);

<div ref={containerRef} className="h-96 overflow-y-auto">
  <HorizontalScrollGallery scroller={containerRef}>
    {items.map((item) => (
      <Card key={item.id} {...item} />
    ))}
  </HorizontalScrollGallery>
</div>;

Guidelines

  • Pass gallery items as children. They are laid out in a horizontal row.
  • When inside a scrollable container, pass scroller={containerRef}.
  • scrollHeight controls how much vertical scroll is needed to traverse the gallery.

Props

All props are optional unless marked required. Use these to customize every aspect of the component.

PropTypeDefaultDescription
childrenReact.ReactNodeGallery items (cards, images). Rendered in a horizontal row.
classNamestringAdditional CSS classes for the wrapper.
scrollerReact.RefObject<HTMLElement | null>Ref to the scroll container. Pass when inside overflow-y-auto.
scrollHeightstring"300%"Height of the vertical scroll runway. Larger = slower horizontal advance.

Examples

Basic

Numbered cards. Scroll vertically to move horizontally through the gallery.

1
2
3
4
5
6
7
8
import { useRef } from "react";
import { HorizontalScrollGallery } from "@/components/horizontal-scroll-gallery";

export function GalleryDemo() {
  const containerRef = useRef<HTMLDivElement>(null);
  return (
    <div
      ref={containerRef}
      className="h-72 overflow-y-auto"
    >
      <HorizontalScrollGallery
        scroller={containerRef}
        scrollHeight="400%"
      >
        {[1, 2, 3, 4, 5, 6].map((i) => (
          <div
            key={i}
            className="flex h-40 w-56 shrink-0 items-center justify-center rounded-lg border border-border bg-muted text-2xl font-bold"
          >
            {i}
          </div>
        ))}
      </HorizontalScrollGallery>
    </div>
  );
}

Made with ❤️ by Pulkit & Cursor :)

© 2026 Pulkit. All rights reserved

DMCA Verified

Last updated: