5 Pure CSS2 with JSPublished 2026-10-05Free · no sign-up
Seven ways to stack cards: a fanned hand of cards, a deck you can flip through, sticky cards that pile up as you scroll, a pile that spreads into a row, notifications that collapse into a stack, a pile of instant photos and a pricing card with layers behind it.
Three cards sit on top of each other, slightly rotated like a held hand of cards, and fan out further on hover or focus. Each card's rotation comes from a custom property, so changing the angle in one place changes the whole fan.
A deck of tip cards where the top card slides away and moves to the back when you press Next. The deck order is real DOM order, so screen readers read the card on top first, and a live region announces which tip is showing.
View code
<div class="sc2"><div class="deck"><article>Tip 1: Name buttons after what they do.</article><article>Tip 2: Keep line length near 65 characters.</article><article>Tip 3: Test with the keyboard first.</article></div><div class="row"><p aria-live="polite">Tip 1 of 3</p><button type="button">Next tip</button></div></div>
var d = document.querySelector('.sc2 .deck'), p = document.querySelector('.sc2 p'), n = 1, busy = false;
document.querySelector('.sc2 button').onclick = function () {
if (busy) return; busy = true;
var top = d.firstElementChild; top.classList.add('out');
setTimeout(function () { top.classList.remove('out'); d.appendChild(top); n = n % 3 + 1; p.textContent = 'Tip ' + n + ' of 3'; busy = false; }, 350);
};
03. Cards That Stack While Scrolling
StackSticky
Inside a scrolling panel, each card is position: sticky with a slightly larger top offset than the last, so cards pile up on each other as you scroll and leave a sliver of each one visible. It is pure CSS and works with the scroll wheel, keyboard and touch.
View code
<div class="sc3" tabindex="0" role="region" aria-label="Project stages, scrollable"><article style="--i:0;--c:#1e3a8a"><h3>Discover</h3><p>Workshops and research.</p></article><article style="--i:1;--c:#5b21b6"><h3>Design</h3><p>Wireframes and visual design.</p></article><article style="--i:2;--c:#9d174d"><h3>Build</h3><p>Front end and integrations.</p></article><article style="--i:3;--c:#065f46"><h3>Launch</h3><p>Testing, training and go-live.</p></article></div>
Four small cards are piled up with negative margins and spread into a neat row when the group is hovered or focused, like a tidy hand of cards. The cards are list items, so the list is announced with its count.
Notification cards collapse into a neat stack with only the edges of older ones peeking out, and expand into a list when the button above them is pressed. The button has aria-expanded, so the collapsed and expanded states are announced.
View code
<div class="sc5"><button type="button" aria-expanded="false" aria-controls="sc5l">3 notifications</button><ul id="sc5l"><li><b>Order shipped</b>Your parcel is on its way.</li><li><b>New review</b>“Lovely mug!” 5 stars.</li><li><b>Payout sent</b>$420 to your bank.</li></ul></div>
var w = document.querySelector('.sc5'), b = w.querySelector('button');
b.onclick = function () { var o = w.classList.toggle('open'); b.setAttribute('aria-expanded', o); };
06. Polaroid Photo Pile
StackGallery
Three instant-photo frames lie on a pile at different angles, and the one under the pointer straightens and rises to the top with a higher z-index. The photos are gradient stand-ins with captions in figcaption elements.
A single pricing card with two offset layers behind it, a quiet way to make the recommended plan feel weightier than its neighbours. The layers are two pseudo-elements, so the markup is just the card.
View code
<article class="sc7"><p class="tag">Most popular</p><h3>Growth</h3><p class="pr"><b>$29</b> / month</p><p class="d">For shops doing their first thousand orders.</p></article>
Putting every card in the same grid area with grid-area: 1 / 1 stacks them without absolute positioning, so the container still sizes itself to the cards. Rotate or offset each one with a custom property.
Order matters for screen readers
Assistive technology reads cards in DOM order, not visual order. Keep the card that looks on top first in the markup, and when a deck changes, move the element in the DOM rather than only changing z-index.
Sticky stacking on scroll
Cards with position: sticky and increasing top values pile on top of each other as the page scrolls past them. It is pure CSS and works with every input method.
Keep the cue when it moves
Fanning or spreading on hover should also happen on :focus-visible, and a stack that hides content needs a button with aria-expanded so everyone can open it.
Frequently asked questions
Why use isolation: isolate?
Cards with negative z-index would otherwise slip behind the page background. isolation creates a new stacking context so they stay inside the component.
Do the stacks work on touch screens?
The deck and notifications use buttons, and the scroll stack uses touch scrolling. Hover-only fans simply stay closed.
Can I put real images in the photo pile?
Yes. Replace the gradient div with an img and keep its alt text.