Motion UIComponentsComponent

Parallax layers

Scroll-linked depth layers that move at different speeds as the page scrolls.

npx shadcn@latest add @motion/parallax-layers

API reference

Components

<ParallaxScene />

The scroll-driving scene root. Attaches the useScroll target to its own element and publishes the scroll progress, the derived travel unit and the resolved motion mode to its ParallaxLayers via context. Static structure of its own - all motion lives in the layers it wraps.

children?

ReactNode

The scene contents: the ParallaxLayers (and any static chrome that should not parallax, e.g. a fixed nav).

className?

string

Merged onto the scene element. Style your section root here (surface, min-height, padding, overflow-hidden to clip the moving layers).

as?

ElementType = "div"

The element type to render for the scene root. Defaults to "div"; pass "section" for a marketing hero. The useScroll target is attached to this element.

offset?

UseScrollOptions["offset"] = DEFAULT_OFFSET

The scroll offset that defines the scene's 0 -> 1 progress passage (a Motion useScroll offset). Defaults to ["start start", "end start"], the standard hero passage.

<ParallaxLayer />

A single depth layer. Reads the enclosing ParallaxScene's scroll progress and moves its content: y throws up by speed x the scene travel unit, and, when scaleDrift is set, scale creeps from 1. Both track raw scroll 1:1 (no spring) and are compositor-only transforms. Under reduced motion the scene pins motionAllowed false and the layer holds still.

children?

ReactNode

The layer's content - your background, product window, copy block, etc.

speed

number

Scroll speed multiplier. 0 pins the layer in place; larger values throw it further up as the scene scrolls (the layer closest to the camera moves fastest). The px thrown is speed x the scene's travel unit.

scaleDrift?

number = 0

Optional scale drift: the layer scales from 1 to 1 + scaleDrift * speed across the scroll, for a slow background that also creeps larger. Defaults to 0 (no scale, and no scale transform is applied).

className?

string

Merged onto the moving element. Position the layer here (e.g. "absolute inset-0 z-0" for a background).

"aria-hidden"?

boolean

Marks the layer aria-hidden - set it on a purely decorative layer (a background texture) so assistive tech skips it.

Hooks

useParallaxScroll

Returns the enclosing ParallaxScene's raw scrollYProgress MotionValue (0 -> 1 across the scene's passage), for deriving your own scroll-linked transforms alongside the layers. Throws if called outside a ParallaxScene.

useParallaxScroll(): MotionValue<number>