Interaction
Card Stack
Scroll-driven sticky card stack with ScrollTrigger. Nest <motion-card-stack-item> elements inside.
Preview
↓ Scroll to reveal
Pure Custom Elements
Ship as .ts
files from a shadcn-compatible registry. Drop them into any HTML, React, or
Vue project.
GSAP-powered motion
Each card pins, then scales as the next one slides in, driven by ScrollTrigger scrub.
Lit under the hood
Framework-agnostic web components via
LitElement. Shadow DOM keeps styles and GSAP logic fully encapsulated.
Hell yeah!
Scroll-driven sticky card stack with GSAP ScrollTrigger. Scroll inside the preview to see the effect.
Attributes
Installation
pnpm dlx motion-blocks add card-stack Usage
---import "@/components/motion-blocks/card-stack-element.ts";import "@/components/motion-blocks/card-stack-item-element.ts";--- <motion-card-stack scroll-element="#scroller" class="p-16"> <motion-card-stack-item class="rounded-2xl bg-white p-8 min-h-[320px]"> <h2>Card 1</h2> <p>Content for the first card</p> </motion-card-stack-item> <motion-card-stack-item class="rounded-2xl bg-slate-50 p-8 min-h-[320px]"> <h2>Card 2</h2> <p>Content for the second card</p> </motion-card-stack-item> <motion-card-stack-item class="rounded-2xl bg-white p-8 min-h-[320px]"> <h2>Card 3</h2> <p>Content for the third card</p> </motion-card-stack-item></motion-card-stack> API Reference
| Attribute | Type | Default |
|---|---|---|
scale-factor How much each card scales down per card (0.05 = 5% smaller each step). | number | 0.05 |
gap Vertical gap between stacked cards in pixels. | number | 0 |
offset Vertical offset between card positions in pixels. | number | 10 |
top-offset Initial top offset for the first card in pixels. | number | 0 |
scroll-element CSS selector for the scrollable container (defaults to window scroll). | string | "" |

