Cards✨ Premium

Stacked Cards

Three stacked cards fan out on hover — pure CSS animation with spring bounce, zero dependencies.

CSSStackHover

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Cards has 41 effects, including 6 free. Explore the category →

3 usage examples

Payment method selector — Stacked Cards example 1

① Payment method selector

WhenA checkout form or wallet screen shows several saved payment cards and the user needs to pick one.
WhyThe effect physically reveals the cards hidden behind the top one, making selection intuitive without cluttering the screen at rest.
SettingstranslateX(±60px) rotate(±10deg) to space out wider card-shaped items; container at 320×200 px; masked card number and network logo on each .card-stack-item.
Photo gallery thumbnail — portfolio — Stacked Cards example 2

② Photo gallery thumbnail — portfolio

WhenA collection thumbnail in a portfolio or media library represents multiple images. The user hovers to discover that more than one visual is available.
WhyThe fan adds depth to the content without opening a modal — a single interaction signals the richness of the collection.
SettingstranslateX(±50px) rotate(±12deg); card background = image thumbnail (background-size: cover); add box-shadow to reinforce the physical stacking feel.
Customer testimonial stack — Stacked Cards example 3

③ Customer testimonial stack

WhenA 'Reviews' section on a landing page displays several testimonials stacked. Hovering reveals their plurality before the user scrolls to the full list.
WhyThe motion suggests the volume of reviews without a carousel or pagination — the top card stays readable at rest, so the main message is never lost.
SettingstranslateX(±45px) rotate(±6deg) for a gentler spread on text-heavy content; transition: 0.5s for a more measured animation on an editorial landing page.

How it works

The three .card-stack-item elements are absolutely positioned inside their container (position: absolute; width: 100%; height: 100%) and perfectly overlap at rest. Stack order is controlled by descending z-index values (3 → 2 → 1 from first to third child): the first child sits on top.

On .card-stack-container hover, the CSS selector :hover .card-stack-item:nth-child(n) applies three distinct transform values: the top card slides left (translateX(-40px) rotate(-8deg)), the middle card lifts up (translateY(-10px) without rotation), and the bottom card slides right (translateX(40px) rotate(8deg)). No script triggers this movement.

The transition uses 0.4s cubic-bezier(.175, .885, .32, 1.275) — a back-out easing where the fourth parameter (1.275 > 1) causes a slight overshoot at the end of travel, giving a natural spring feel on landing.

Only the transform property is animated: browsers composite this property on the GPU, avoiding any page reflow or repaint. The effect stays performant even on dense card lists.

Accessibility

  • prefers-reduced-motion: ABSENT from the base code. No @media (prefers-reduced-motion: reduce) rule is present — the transition fires regardless of system preference. Add @media (prefers-reduced-motion: reduce) { .card-stack-item { transition: none } } if the animation may cause discomfort.
  • Keyboard interaction: the effect relies solely on :hover (mouse only). Keyboard users do not see the fan. To fix this, replace :hover with :hover, :focus-within on .card-stack-container.
  • Text contrast: cards use purple-to-fuchsia gradients (#6366f1 → #d946ef) on a #12121a background. White text on these gradients comfortably exceeds the WCAG AA ratio (≥ 4.5:1).
  • Semantics: the container is a plain <div> with no ARIA role. If the cards represent functional content (selection, navigation), add role="group" and an aria-label describing the set.
  • Touch: on mobile, :hover fires on first tap and resets on the second — native browser behavior, generally acceptable for a purely decorative effect.

Browser compatibility

100% CSS effect — transforms and transitions. Supported in all modern browsers since 2015.

Chrome 36+✓ Full
Firefox 16+✓ Full
Safari 9+✓ Full
Edge 12+✓ Full
Mobile iOS✓ Tap OK
Android Chrome✓ Full

Without CSS transition support, cards overlap and snap apart instantly on hover — no script crashes, the layout stays intact.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="card-stack-container">
  <div class="card-stack-item">Card 1</div>
  <div class="card-stack-item">Card 2</div>
  <div class="card-stack-item">Card 3</div>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
--bg-card #12121a CSS variable — fallback background color for cards. Replace with your brand card background if not using a gradient.
--radius-xl 1rem CSS variable — corner radius of each card. Increase (e.g. 1.5rem) for a rounder look, decrease (e.g. 0.5rem) for angular styling.
--border rgba(255,255,255,0.08) CSS variable — card border color and opacity. Raise the opacity (e.g. 0.20) for a more defined edge on light backgrounds.
translateX(±40px) ±40px Lateral spread distance (nth-child 1 and 3 lines in the :hover block). Increase to space cards further apart (e.g. ±60px for wider payment-card shapes).
rotate(±8deg) ±8deg Tilt angle of the side cards. Decrease (e.g. ±4deg) for a subtle effect, increase (e.g. ±14deg) for an expressive fan.
translateY(-10px) -10px Lift of the center card on hover. Set to 0 to remove it, increase (e.g. -20px) for a more pronounced rise.
transition: .4s cubic-bezier(…) .4s / back-out Duration and easing for all cards (transition line on .card-stack-item). Replace with 0.25s ease-out to remove the bounce, or 0.6s to slow it down.
background (nth-child) indigo→fuchsia gradients Each card has its own background on :nth-child(1/2/3). Replace with a solid color, brand gradient, or background-image for illustrated content.

FAQ

No, Stacked Cards is 100% CSS. The hover fan is driven by a :hover selector with transform and transition — no script needed. It integrates natively into React, Vue, Svelte, or any other framework without directives or hooks.
Add more .card-stack-item elements inside the container and extend the :nth-child(n) selectors in the :hover block. Distribute rotations symmetrically (e.g. ±6° / 0° / ±12° for 4 cards) and adjust translateX values to avoid overlap.
With pure CSS, use the checkbox hack: a hidden <input type="checkbox"> paired with a label fires the :checked state, which activates the transform values via an adjacent sibling selector. For more control (programmatic toggle, persistent state), one line of JS is enough: add or remove a class on the container on click.