Skip to content

Scroll Stack

Cards collect into a layered stack as you scroll.

LIVE PREVIEWInteract with the component
Just React. No extra dependencies.

Copy the component and its CSS module into your project.

CSS Modules

Usage

Matches your current playground settings.

jsx
import ScrollStack from "./ScrollStack";
export default function Example() {
return (
<ScrollStack
items={[
{
"id": "form",
"title": "01 - Form",
"description": "Start with a shape.",
"background": "radial-gradient(ellipse at 100% 0%, #f4c4a8, transparent 60%), #d3bcaa",
"color": "#392c2a"
},
{
"id": "colour",
"title": "02 - Colour",
"description": "Find a different combination.",
"background": "radial-gradient(ellipse at 0% 100%, #d4bcdf, transparent 65%), #8d7b9d",
"color": "#241b2e"
},
{
"id": "motion",
"title": "03 - Motion",
"description": "Bring the details to life.",
"background": "radial-gradient(ellipse at 100% 0%, #9bacaa, transparent 65%), #3f5b60",
"color": "#f0f4e8"
}
]}
height={460}
cardHeight={280}
gap={70}
stackOffset={12}
scaleStep={0.06}
/>
);
}

Using Scroll Stack

Supply the panels through items and set height for the scrolling viewport. cardHeight should accommodate the content of an individual panel.

stackOffset and scaleStep control how accumulated cards remain visible. Use onActiveChange when the selected panel also drives content outside the stack.

Props

NameTypeRequiredDefaultDescription
itemsobject[]No[]Array of { id, content?, title?, description?, image?, background?, color? }. content accepts a React node. Empty arrays render nothing.
heightnumber | stringNo460Height of the independently scrollable viewport, in pixels or a CSS length.
cardHeightnumberNo280Height of each card in pixels.
gapnumberNo70Vertical travel between cards in pixels.
stackOffsetnumberNo12Sticky offset between each layer, in pixels.
scaleStepnumberNo0.06Scale reduction per card passed, with a minimum scale of 0.75.
onActiveChangefunctionNoundefinedCalled with the nearest card index as the viewport scrolls.
labelstringNo"Scrollable card stack"Accessible label for the keyboard-focusable scroll region.
classNamestringNo""Additional CSS classes, merged with the component styles.
styleCSSPropertiesNoundefinedInline styles for caller-defined sizing and visual overrides.

Related components

A paper flap lifts in 3D as a message slides out of its envelope.

A lightly textured receipt pairs precise item rows with a torn paper edge.

A suspended badge swings naturally after you drag and release its handle.

Fine metallic grooves catch a shifting iridescent pointer highlight.