Scroll-Linked Video Scrubber

Sticky video that scrubs forward/backward as you scroll. Uses a tall wrapper and position: sticky — no scroll hijacking.

Component

Installation

pnpm dlx shadcn@latest add "https://pulkitxm.com/components/scroll-linked-video-scrubber.json"

Usage

Import

Add the imports.

import { useRef } from "react";
import { ScrollLinkedVideoScrubber } from "@/components/scroll-linked-video-scrubber";

Use

Wrap in a scrollable container. Pass scroller ref. scrollHeight controls scrub speed.

const containerRef = useRef<HTMLDivElement>(null);

<div
  ref={containerRef}
  className="h-screen overflow-y-auto"
>
  <ScrollLinkedVideoScrubber
    src="/components/scroll-linked-video-scrubber/demo.mp4"
    scroller={containerRef}
    scrollHeight="500%"
  />
</div>;

Guidelines

  • Pass src for the video URL. Video must be same-origin or CORS-enabled for duration access.
  • When inside a scrollable container (demo, modal), pass scroller={containerRef}.
  • scrollHeight controls how much scroll is needed to play the full video (default '300%').
  • No extra spacer divs needed — the component creates its own scroll runway.

Props

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

PropTypeDefaultDescription
srcrequiredstringVideo source URL.
classNamestringAdditional CSS classes for the outer wrapper.
videoClassNamestringClasses for the video element.
scrollerReact.RefObject<HTMLElement | null>Ref to the scroll container. When inside overflow-y-auto, pass its ref so scroll events track that element.
posterstringPoster image URL.
mutedbooleantrueMute the video (recommended for autoplay policies).
playsInlinebooleantrueplaysInline for mobile.
scrollHeightstring"300%"Height of the scroll runway. Larger values = slower scrub. Accepts any CSS height value.

Examples

Basic

Basic usage. Pass scroller ref when inside a scrollable container.

import { useRef } from "react";
import { ScrollLinkedVideoScrubber } from "@/components/scroll-linked-video-scrubber";

export function VideoScrubberDemo() {
  const containerRef = useRef<HTMLDivElement>(null);
  return (
    <div
      ref={containerRef}
      className="h-96 overflow-y-auto"
    >
      <ScrollLinkedVideoScrubber
        src="/components/scroll-linked-video-scrubber/demo.mp4"
        scroller={containerRef}
        scrollHeight="500%"
      />
    </div>
  );
}

Made with ❤️ by Pulkit & Cursor :)

© 2026 Pulkit. All rights reserved

DMCA Verified

Last updated: