scroll-reveal
Pure CSSNo JavaScriptAccessible

Scroll-driven
storytelling
for shadcn/ui

Sticky image reveals with animated captions. Built on the CSS Scroll-Driven Animations API. Zero JavaScript, fully accessible, respects prefers-reduced-motion.

pnpm dlx shadcn@latest add https://shadcn-scroll-reveal.vercel.appr/scroll-reveal.json

Scroll to see it live

scroll-reveal.tsx
<ScrollReveal
imageEnter="left"
captionMotion="left-center"
imageStickTop="4.5rem"
image={<img />}
caption={<p />}
/>
Pure CSSNo JSprefers-reduced-motionanimation-timeline: view()
01

Image enters from the left

Add imageEnter="left" to slide the image in from the left as it enters the viewport. The caption appears in its natural flow position below the sticky image.

imageEnter="left"

The image slides in from the left. No captionMotion applied — the caption appears in its natural position below.

02

Caption sweeps in from the side

Combine imageEnter="bottom" with captionMotion="left-center" — the caption starts off-screen and lands in the center reading position as you scroll.

captionMotion="left-center"

The caption animates from off-screen left into the center reading position. Great for body text you want users to actually read.

03

Full pass-through motion

Use captionMotion="right-left" for a dramatic full-width sweep. Works best for short labels — reduce captionMaxWidth for a tighter card.

captionMotion="right-left"

The caption crosses the full width of the stage. Use a smaller captionMaxWidth for pass-through effects.

Installing

Install Scroll Reveal using the shadcn CLI.
pnpm dlx shadcn@latest add https://shadcn-scroll-reveal.vercel.appr/scroll-reveal.json

Props

Every CSS custom property is exposed as a typed React prop.

PropTypeDefault
image*
ReactNode
caption
ReactNode
imageEnter
"left" | "right" | "top" | "bottom" | "none""bottom"
captionMotion
"left-center" | "right-center" | "left-right" | "right-left"
sceneDuration
string"220svh"
imageHeight
string"66svh"
imageStickTop
string"0"
captionDelay
string"40svh"
captionMotionDistance
string"80vw"
sceneExitSpace
string"55svh"
captionMaxWidth
string"52rem"
imageFit
"cover" | "contain""cover"
imagePosition
string"center"
imageStartScale
string".96"

Basic usage

my-page.tsx
import { ScrollReveal } from "@/components/scroll-reveal/scroll-reveal"

<ScrollReveal
  imageEnter="left"
  imageStickTop="4.5rem"
  image={<img src="/hero.jpg" alt="..." />}
  caption={
    <>
      <h2>Your headline</h2>
      <p>A short caption that appears as you scroll.</p>
    </>
  }
/>

Find it useful?

Star the repo and share it with your team.

Star on GitHub

0 bytes

Runtime JS

none

Dependencies

scroll-driven

Browser API

supported

Reduced motion