Stacking Cards
A component used in websites to display layered cards that stack on top of one another, often with interactive animations.
by Khoa Phan
The Guiding Light
Lighthouses have stood as beacons of hope for centuries, guiding sailors safely through treacherous waters. Their glowing light and towering presence serve as a reminder of humanity’s connection to the sea.
Life Beneath the Waves
From shimmering schools of fish to solitary hunters, the ocean is home to an incredible variety of marine life. Each species plays a vital role in maintaining the balance of underwater ecosystems.
Alone on the Open Sea
Drifting across the endless horizon, traveling alone on the sea is a test of courage and resilience. With nothing but the waves and the sky, solitude becomes both a challenge and a source of deep reflection.
The Art of Sailing
Harnessing the power of the wind, sailing is both a skill and an adventure. Whether racing across the waves or leisurely cruising, it’s a timeless way to explore the vast blue expanse.
The Era of Whaling
Once a thriving industry, whale hunting shaped economies and cultures across the world. Today, efforts to protect these majestic creatures highlight the shift toward conservation and respect for marine life.
fancy
Installation
npx shadcn@latest add "https://fancycomponents.dev/r/stacking-cards.json"
Usage
Wrap StackingCards
around the content you want to animate and StackingCardItem
around each card you want to animate.
The structure looks like this:
<StackingCards>
<StackingCardItem>
{/* Your card go here */}
</StackingCardItem>
</StackingCards>
Understanding the component
The component utilizes scroll progress to determine the scale of each element. The first element has the highest scale multiplier, making it the smallest when it reaches the bottom of the container's scroll area, while the last element follows the opposite pattern, creating a layered effect.
To achieve this, I use each element's index to calculate its scale multiplier. Just simple as that! 😀
Notes
-
By default, this component uses the
window
to track scroll progress. However, in some cases, you may want to wrap it inside another scrollable container. To achieve this, simply define the container foruseScroll
frommotion
. In theDemo
above, I defined thecontainerRef
and passed it to thescrollOptions
prop of theStackingCards
component. -
To ensure
StackingCardItem
works correctly, you need to define its height. This allows the wrapper to have a larger height than the card itself, ensuring that thetopPosition
functions properly.
Props
StackingCards
Prop | Type | Default | Description |
---|---|---|---|
totalCards* | number | 0 | Total number of cards to be animated (this is for calculating the scale intensity) |
scaleMultiplier | number | 0.03 | The intensity of the card to scale |
scrollOptons | UseScrollOptions | {offset: ["start start", "end end"]} | Scroll options for useScroll hook from motion . |
className | string | - | className for the container |
Other Props | - | - | All attributes for HTMLDivElement |
StackingCardItem
Prop | Type | Default | Description |
---|---|---|---|
index* | number | - |
|
topPosition | string | 5 + index * 3 | The top position of the card |
className | string | - | className for the StackingCardItem element |
Other Props | - | - | All attributes for HTMLDivElement |