36 Tailwind Stacked Cards
15 / 36

All 36 in 36 Tailwind Stacked Cards

  1. 01Tailwind Scroll-Driven Scaling Card Stack
  2. 02Tailwind Swipe Card Deck Drag to Dismiss
  3. 03Tailwind Glassmorphism Testimonial Card Stack
  4. 04Tailwind Stacked Cards Expand Accordion on Click
  5. 05Tailwind Fan Out Photo Stack on Hover
  6. 06Tailwind 3D Perspective Tilt Card Stack
  7. 07Tailwind Multi Step Form Card Stack
  8. 08Tailwind Tabbed Card Stack Bring to Front
  9. 09Tailwind Click to Front Stacked Cards Cycle
  10. 10Tailwind Classic Card Deck Stack Shadow
  11. 11Tailwind Fan Spread Hand of Cards
  12. 12Tailwind Polaroid Photo Stack Scattered Rotate
  13. 13Tailwind Staircase Offset Stacked Cards Cascade
  14. 14Tailwind Cards Spread Out Horizontally on Hover
  15. 15Tailwind Stacked Cards Lift on Hover Sibling Push
  16. 16Tailwind Accordion Stacked Cards Slide Out Menu
  17. 17Tailwind Shuffle Cards Animation Loop Deck
  18. 18Tailwind File Folder Tab Stacked Cards
  19. 19Tailwind Scattered Photos Pinch to Centre on Hover
  20. 20Tailwind Mobile Swipe Card Stack Translate3d
  21. 21Tailwind Single Accordion Card Nested Layers
  22. 22Tailwind Isometric Tower Stacked Cards 3D Column
  23. 23Tailwind 3D Flip Card Stack Reveal Back
  24. 24Tailwind Card Stack Tilt on Hover Quadrant
  25. 25Tailwind Notification Stack Pile Dismiss
  26. 26Tailwind Receipt Roll Unroll Stacked Items
  27. 27Tailwind Scratch Card Reveal Canvas Mask
  28. 28Tailwind Stacked Cards Hover Reveal Spread
  29. 29Tailwind Scroll Activated Sticky Stacking Cards
  30. 30Tailwind Stacked Testimonial Slider Radio
  31. 31Tailwind Isometric Overlapping Stacked Cards
  32. 32Tailwind Bento Grid Stacked Cards Hover Fan
  33. 33Tailwind Perspective Card Deck Depth Tunnel
  34. 34Tailwind Peel Back Corner Card Reveal
  35. 35Tailwind Timeline Stacked Milestone Cards
  36. 36Tailwind Spiral Tower Rotating Stacked Cards
Tailwind v4MIT licensed

Tailwind Stacked Cards Lift on Hover Sibling Push

The parting-of-the-waters stack: hover a card and every card below it slides down. This is the demo where Tailwind runs out of variants — there is no hover ~ sibling family — so the whole effect rides one arbitrary variant, [&:hover~*]:translate-y-[30px], typed on each card. Worth knowing precisely because it is the exception rather than the rule.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="stk-15 w-full min-h-svh flex items-center justify-center px-5 py-15 font-stk15-sans bg-stk15-bg" aria-label="Cascade-lift card stack">
  <div class="w-[min(320px,100%)]">
    <a class="flex flex-col gap-1.25 -mt-4 first:mt-0 rounded-2xl bg-stk15-c1 px-6 py-5 text-white no-underline shadow-[0_14px_30px_-18px_rgba(0,0,0,0.8)] transition-[transform,box-shadow] duration-350 ease-stk15 hover:z-5 hover:-translate-y-[18px] hover:scale-[1.03] hover:shadow-[0_26px_44px_-20px_rgba(0,0,0,0.9)] focus-visible:z-5 focus-visible:outline-none focus-visible:-translate-y-[18px] focus-visible:scale-[1.03] focus-visible:shadow-[0_0_0_3px_#fff,0_26px_44px_-20px_rgba(0,0,0,0.9)] [&:hover~*]:translate-y-[30px] [&:focus-visible~*]:translate-y-[30px] motion-reduce:transition-[box-shadow]" href="#">
      <b class="text-lg font-extrabold tracking-[-0.02em]">Espresso</b>
      <span class="font-stk15-mono text-[13px] opacity-90">Single origin &middot; 30&thinsp;ml</span>
    </a>
    <a class="flex flex-col gap-1.25 -mt-4 rounded-2xl bg-stk15-c2 px-6 py-5 text-white no-underline shadow-[0_14px_30px_-18px_rgba(0,0,0,0.8)] transition-[transform,box-shadow] duration-350 ease-stk15 hover:z-5 hover:-translate-y-[18px] hover:scale-[1.03] hover:shadow-[0_26px_44px_-20px_rgba(0,0,0,0.9)] focus-visible:z-5 focus-visible:outline-none focus-visible:-translate-y-[18px] focus-visible:scale-[1.03] focus-visible:shadow-[0_0_0_3px_#fff,0_26px_44px_-20px_rgba(0,0,0,0.9)] [&:hover~*]:translate-y-[30px] [&:focus-visible~*]:translate-y-[30px] motion-reduce:transition-[box-shadow]" href="#">
      <b class="text-lg font-extrabold tracking-[-0.02em]">Cortado</b>
      <span class="font-stk15-mono text-[13px] opacity-90">Equal parts &middot; 90&thinsp;ml</span>
    </a>
    <a class="flex flex-col gap-1.25 -mt-4 rounded-2xl bg-stk15-c3 px-6 py-5 text-white no-underline shadow-[0_14px_30px_-18px_rgba(0,0,0,0.8)] transition-[transform,box-shadow] duration-350 ease-stk15 hover:z-5 hover:-translate-y-[18px] hover:scale-[1.03] hover:shadow-[0_26px_44px_-20px_rgba(0,0,0,0.9)] focus-visible:z-5 focus-visible:outline-none focus-visible:-translate-y-[18px] focus-visible:scale-[1.03] focus-visible:shadow-[0_0_0_3px_#fff,0_26px_44px_-20px_rgba(0,0,0,0.9)] [&:hover~*]:translate-y-[30px] [&:focus-visible~*]:translate-y-[30px] motion-reduce:transition-[box-shadow]" href="#">
      <b class="text-lg font-extrabold tracking-[-0.02em]">Flat white</b>
      <span class="font-stk15-mono text-[13px] opacity-90">Micro-foam &middot; 160&thinsp;ml</span>
    </a>
    <a class="flex flex-col gap-1.25 -mt-4 rounded-2xl bg-stk15-c4 px-6 py-5 text-white no-underline shadow-[0_14px_30px_-18px_rgba(0,0,0,0.8)] transition-[transform,box-shadow] duration-350 ease-stk15 hover:z-5 hover:-translate-y-[18px] hover:scale-[1.03] hover:shadow-[0_26px_44px_-20px_rgba(0,0,0,0.9)] focus-visible:z-5 focus-visible:outline-none focus-visible:-translate-y-[18px] focus-visible:scale-[1.03] focus-visible:shadow-[0_0_0_3px_#fff,0_26px_44px_-20px_rgba(0,0,0,0.9)] [&:hover~*]:translate-y-[30px] [&:focus-visible~*]:translate-y-[30px] motion-reduce:transition-[box-shadow]" href="#">
      <b class="text-lg font-extrabold tracking-[-0.02em]">Cold brew</b>
      <span class="font-stk15-mono text-[13px] opacity-90">18&thinsp;h steep &middot; 240&thinsp;ml</span>
    </a>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-stk15-bg: #161310;
  --color-stk15-bg: oklch(0.20 0.012 60);
  --color-stk15-c1: #cf5f4b;
  --color-stk15-c1: oklch(0.62 0.16 20);
  --color-stk15-c2: #bd7440;
  --color-stk15-c2: oklch(0.60 0.14 50);
  --color-stk15-c3: #a38434;
  --color-stk15-c3: oklch(0.58 0.12 80);
  --color-stk15-c4: #859030;
  --color-stk15-c4: oklch(0.58 0.10 110);
  --font-stk15-sans: 'Archivo', system-ui, sans-serif;
  --font-stk15-mono: 'JetBrains Mono', ui-monospace, monospace;
  --ease-stk15: cubic-bezier(0.3, 0.9, 0.3, 1);
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

Compiles in the browser — perfect for a CodePen or a quick test, not for production.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-stk15-bg: #161310;
  --color-stk15-bg: oklch(0.20 0.012 60);
  --color-stk15-c1: #cf5f4b;
  --color-stk15-c1: oklch(0.62 0.16 20);
  --color-stk15-c2: #bd7440;
  --color-stk15-c2: oklch(0.60 0.14 50);
  --color-stk15-c3: #a38434;
  --color-stk15-c3: oklch(0.58 0.12 80);
  --color-stk15-c4: #859030;
  --color-stk15-c4: oklch(0.58 0.10 110);
  --font-stk15-sans: 'Archivo', system-ui, sans-serif;
  --font-stk15-mono: 'JetBrains Mono', ui-monospace, monospace;
  --ease-stk15: cubic-bezier(0.3, 0.9, 0.3, 1);
}
3Fonts used by this demooptional — skip if you have your own type stack
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo:wdth,wght@75..125,400;75..125,800&family=JetBrains+Mono:wght@400;500&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • The webfonts load as <link> tags in setup, not as an @import inside the stylesheet. Tailwind emits user @import rules after its own @layer blocks, and a late @import is invalid CSS — the browser drops it and the demo silently falls back to system fonts.
  • This is the collection's one arbitrary variant: [&:hover~*]:translate-y-[30px]. Tailwind covers self, ancestor and earlier-sibling state, but not &lsquo;me hovered, later siblings styled&rsquo;.
  • A group cannot substitute. The parent would know that something is hovered but not which card, and the whole effect depends on which.
  • The keyboard twin needs its own arbitrary variant too — [&:focus-visible~*]: — and forgetting it is invisible to anyone testing with a mouse.
  • The stack stays in normal document flow, so unlike the absolute stacks here it needs no fixed height and reflows freely at narrow widths.
  • The lift is a transform and the overlap is a margin: the margin is static, the transform is animated, and the column never relayouts mid-hover.
  • motion-reduce:transition-[box-shadow] keeps the depth response and removes the movement, rather than slowing it down.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Stacked Cards Lift on Hover Sibling Push
Source: https://codefronts.com/components/tailwind-stacked-cards/tailwind-stacked-cards-lift-on-hover-sibling-push/

The parting-of-the-waters stack: hover a card and every card below it slides down. This is the demo where Tailwind runs out of variants &mdash; there is no hover ~ sibling family &mdash; so the whole effect rides one arbitrary variant, [&:hover~*]:translate-y-[30px], typed on each card. Worth knowing precisely because it is the exception rather than the rule.
## HTML
```html
<section class="stk-15 w-full min-h-svh flex items-center justify-center px-5 py-15 font-stk15-sans bg-stk15-bg" aria-label="Cascade-lift card stack">
  <div class="w-[min(320px,100%)]">
    <a class="flex flex-col gap-1.25 -mt-4 first:mt-0 rounded-2xl bg-stk15-c1 px-6 py-5 text-white no-underline shadow-[0_14px_30px_-18px_rgba(0,0,0,0.8)] transition-[transform,box-shadow] duration-350 ease-stk15 hover:z-5 hover:-translate-y-[18px] hover:scale-[1.03] hover:shadow-[0_26px_44px_-20px_rgba(0,0,0,0.9)] focus-visible:z-5 focus-visible:outline-none focus-visible:-translate-y-[18px] focus-visible:scale-[1.03] focus-visible:shadow-[0_0_0_3px_#fff,0_26px_44px_-20px_rgba(0,0,0,0.9)] [&:hover~*]:translate-y-[30px] [&:focus-visible~*]:translate-y-[30px] motion-reduce:transition-[box-shadow]" href="#">
      <b class="text-lg font-extrabold tracking-[-0.02em]">Espresso</b>
      <span class="font-stk15-mono text-[13px] opacity-90">Single origin &middot; 30&thinsp;ml</span>
    </a>
    <a class="flex flex-col gap-1.25 -mt-4 rounded-2xl bg-stk15-c2 px-6 py-5 text-white no-underline shadow-[0_14px_30px_-18px_rgba(0,0,0,0.8)] transition-[transform,box-shadow] duration-350 ease-stk15 hover:z-5 hover:-translate-y-[18px] hover:scale-[1.03] hover:shadow-[0_26px_44px_-20px_rgba(0,0,0,0.9)] focus-visible:z-5 focus-visible:outline-none focus-visible:-translate-y-[18px] focus-visible:scale-[1.03] focus-visible:shadow-[0_0_0_3px_#fff,0_26px_44px_-20px_rgba(0,0,0,0.9)] [&:hover~*]:translate-y-[30px] [&:focus-visible~*]:translate-y-[30px] motion-reduce:transition-[box-shadow]" href="#">
      <b class="text-lg font-extrabold tracking-[-0.02em]">Cortado</b>
      <span class="font-stk15-mono text-[13px] opacity-90">Equal parts &middot; 90&thinsp;ml</span>
    </a>
    <a class="flex flex-col gap-1.25 -mt-4 rounded-2xl bg-stk15-c3 px-6 py-5 text-white no-underline shadow-[0_14px_30px_-18px_rgba(0,0,0,0.8)] transition-[transform,box-shadow] duration-350 ease-stk15 hover:z-5 hover:-translate-y-[18px] hover:scale-[1.03] hover:shadow-[0_26px_44px_-20px_rgba(0,0,0,0.9)] focus-visible:z-5 focus-visible:outline-none focus-visible:-translate-y-[18px] focus-visible:scale-[1.03] focus-visible:shadow-[0_0_0_3px_#fff,0_26px_44px_-20px_rgba(0,0,0,0.9)] [&:hover~*]:translate-y-[30px] [&:focus-visible~*]:translate-y-[30px] motion-reduce:transition-[box-shadow]" href="#">
      <b class="text-lg font-extrabold tracking-[-0.02em]">Flat white</b>
      <span class="font-stk15-mono text-[13px] opacity-90">Micro-foam &middot; 160&thinsp;ml</span>
    </a>
    <a class="flex flex-col gap-1.25 -mt-4 rounded-2xl bg-stk15-c4 px-6 py-5 text-white no-underline shadow-[0_14px_30px_-18px_rgba(0,0,0,0.8)] transition-[transform,box-shadow] duration-350 ease-stk15 hover:z-5 hover:-translate-y-[18px] hover:scale-[1.03] hover:shadow-[0_26px_44px_-20px_rgba(0,0,0,0.9)] focus-visible:z-5 focus-visible:outline-none focus-visible:-translate-y-[18px] focus-visible:scale-[1.03] focus-visible:shadow-[0_0_0_3px_#fff,0_26px_44px_-20px_rgba(0,0,0,0.9)] [&:hover~*]:translate-y-[30px] [&:focus-visible~*]:translate-y-[30px] motion-reduce:transition-[box-shadow]" href="#">
      <b class="text-lg font-extrabold tracking-[-0.02em]">Cold brew</b>
      <span class="font-stk15-mono text-[13px] opacity-90">18&thinsp;h steep &middot; 240&thinsp;ml</span>
    </a>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-stk15-bg: #161310;
  --color-stk15-bg: oklch(0.20 0.012 60);
  --color-stk15-c1: #cf5f4b;
  --color-stk15-c1: oklch(0.62 0.16 20);
  --color-stk15-c2: #bd7440;
  --color-stk15-c2: oklch(0.60 0.14 50);
  --color-stk15-c3: #a38434;
  --color-stk15-c3: oklch(0.58 0.12 80);
  --color-stk15-c4: #859030;
  --color-stk15-c4: oklch(0.58 0.10 110);
  --font-stk15-sans: 'Archivo', system-ui, sans-serif;
  --font-stk15-mono: 'JetBrains Mono', ui-monospace, monospace;
  --ease-stk15: cubic-bezier(0.3, 0.9, 0.3, 1);
}
```

How this works

Where utilities stop. Tailwind's variants describe an element's own state (hover:), an ancestor's (group-hover:) or an earlier sibling's (peer-*). What this pattern needs is the opposite direction: this element hovered, styling later siblings. That is &:hover ~ *, and the arbitrary-variant syntax is the honest way to say it:

class="… [&:hover~*]:translate-y-[30px]
       [&:focus-visible~*]:translate-y-[30px]"

Every card carries it, so any card hovered pushes everything after it. One class does what a .card:hover ~ .card rule does, and it is the only construct in the collection that reaches for a raw selector.

Why not a group? Wrapping in a group would let the parent know something is hovered, but not which card — and the whole effect depends on which. This is a case where the sibling combinator is not a stylistic preference; it is the mechanism.

Flow, not absolute. The cards overlap with a negative top margin and stay in normal flow, which is why this stack needs no fixed height, wraps happily at narrow widths, and never clips.

Make it yours

  • Change the overlap with -mt-4; keep the resting peek taller than the card's padding or the top edges stop being hoverable.
  • Set how far the lower cards move with the 30px in the arbitrary variant.
  • Adjust the lift with hover:-translate-y-[18px] hover:scale-[1.03].
  • Recolour per item — each card carries its own bg-stk15-* token, walking one hue ramp.
  • Add items freely; the sibling variant has no index and does not care how many there are.

Gotchas — read before shipping

  • It must be ~, not +. The adjacent-sibling combinator moves only the next card and the parting collapses.
  • Include the :focus-visible twin. Hover-only means a keyboard user gets the lift with none of the space it needs.
  • Arbitrary variants are an escape hatch, not a habit. If a built-in variant covers your case, use it — raw selectors do not get the compiler's checking.
  • Keep enough peek that every card is hoverable, including the ones under the lifted card.
  • hover:z-5 is needed because the lifted card overlaps the one above it as well as the one below.
  • Do not animate margin here. The lift is a transform so it stays on the compositor; margin would relayout the column on every hover.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

The general-sibling combinator and transforms are universal (Chrome 49+, Safari 10+, Firefox 52+). The floor is Tailwind v4's own generated sheet.

Techniques used in this demo

Theme tokensset in @theme, used by a utility

Arbitraryneeds bracket syntax

HTML & JSno Tailwind involved

Search CodeFronts

Loading…