Stacked Cards
You know that effect where cards stack on top of each other, each one a bit smaller and pushed back? That is what we are building. Each card looks like it is moving away from you into the page.

New house available in Brooklyn
Check out this house before it’s gone

How are you doing today?
Check this guide how you can improve …

Check out this amazing thing!
Look at our new blogpost containing new things
The trick is two CSS properties: scale() makes cards smaller, and translateY() moves them around. That’s it.
Step 1: Layer Cards on Top
First, get three cards to sit in the same spot. We will use CSS Grid:
<div class="wrapper" style="height: 100%;">
<article class="card"></article>
<article class="card"></article>
<article class="card"></article>
</div>All three cards are now stacked on top of each other. They look the same, so you can’t see them.
Step 2: Make Cards Get Smaller as They Go Back
Now shrink each card and move it up. The cards in back get smaller:
<div class="wrapper">
<article class="card"></article>
<article class="card"></article>
<article class="card"></article>
</div>The front card stays full size. The second card is 96% size. The back card is 92%.
The translateY with negative values move cards up. This matters because a smaller card looks lower naturally. If we don’t move it up, it will look below the front card instead of behind it. That breaks the effect.
Step 3: Make It Work with Any Number of Cards
The problem: hardcoding each card’s styles sucks. What if you have 5 cards? 10?
Solution: use CSS variables. Pass an --index to each card (0 for front, 1 for second, etc…), and let CSS do the math:
<div class="wrapper">
<article class="card" style="--index: 0"></article>
<article class="card" style="--index: 1"></article>
<article class="card" style="--index: 2"></article>
</div> Attention!
Attention!
We multiply by -1 to reverse the direction. Without it, higher index means bigger cards. With it, higher index means smaller.
Front card (index 0): 1 - (0 * 0.02) = 1.0
Second card (index 1): 1 - (1 * 0.02) = 0.98
Same for translateY. Negative moves up, so smaller cards sit behind the front one.
That’s it. Two CSS properties. Two variables. Infinite cards.