36 Tailwind Stacked Cards
12 / 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 Polaroid Photo Stack Scattered Rotate

Snapshots tossed on a table: thick white frames, handwritten captions, deliberate mess. Each snap's position is three numbers on the element (--x, --y, --r) and hovering zeroes the rotation while raising z-10, so the one you are looking at pops clean out of the pile. The captions carry a --font-* theme entry, which is how a second typeface becomes font-stk12-hand rather than a one-off 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-12 w-full min-h-svh flex items-center justify-center px-5 py-15 font-stk12-sans bg-stk12-table" aria-label="Scattered Polaroid photos">
  <div class="relative w-[min(360px,90vw)] h-85">
    <figure class="absolute left-1/2 top-1/2 -ml-22.5 -mt-27.5 w-45 cursor-pointer rounded-[3px] bg-white p-3 pb-0 shadow-[0_16px_30px_-14px_rgba(40,30,10,0.6)] [transform:translate(var(--x),var(--y))_rotate(var(--r))] transition-[transform,box-shadow] duration-350 ease-stk12 hover:z-10 hover:shadow-[0_30px_50px_-18px_rgba(40,30,10,0.75)] hover:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] focus-visible:z-10 focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--color-stk12-ring),0_30px_50px_-18px_rgba(40,30,10,0.75)] focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] motion-reduce:hover:[transform:translate(var(--x),var(--y))_rotate(0deg)] motion-reduce:focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)]" tabindex="0" style="--x:-90px;--y:-30px;--r:-8deg">
      <img class="block w-full h-37.5 object-cover" src="https://picsum.photos/seed/tw-pola-1/300/300" width="300" height="300" alt="Tent pitched beside a lake at dawn">
      <figcaption class="px-1 pt-3 pb-3.5 text-center font-stk12-hand text-base text-stk12-ink">Dawn, day 3</figcaption>
    </figure>
    <figure class="absolute left-1/2 top-1/2 -ml-22.5 -mt-27.5 w-45 cursor-pointer rounded-[3px] bg-white p-3 pb-0 shadow-[0_16px_30px_-14px_rgba(40,30,10,0.6)] [transform:translate(var(--x),var(--y))_rotate(var(--r))] transition-[transform,box-shadow] duration-350 ease-stk12 hover:z-10 hover:shadow-[0_30px_50px_-18px_rgba(40,30,10,0.75)] hover:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] focus-visible:z-10 focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--color-stk12-ring),0_30px_50px_-18px_rgba(40,30,10,0.75)] focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] motion-reduce:hover:[transform:translate(var(--x),var(--y))_rotate(0deg)] motion-reduce:focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)]" tabindex="0" style="--x:30px;--y:-50px;--r:6deg">
      <img class="block w-full h-37.5 object-cover" src="https://picsum.photos/seed/tw-pola-2/300/300" width="300" height="300" alt="Two enamel mugs of coffee on a camp stove">
      <figcaption class="px-1 pt-3 pb-3.5 text-center font-stk12-hand text-base text-stk12-ink">First light coffee</figcaption>
    </figure>
    <figure class="absolute left-1/2 top-1/2 -ml-22.5 -mt-27.5 w-45 cursor-pointer rounded-[3px] bg-white p-3 pb-0 shadow-[0_16px_30px_-14px_rgba(40,30,10,0.6)] [transform:translate(var(--x),var(--y))_rotate(var(--r))] transition-[transform,box-shadow] duration-350 ease-stk12 hover:z-10 hover:shadow-[0_30px_50px_-18px_rgba(40,30,10,0.75)] hover:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] focus-visible:z-10 focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--color-stk12-ring),0_30px_50px_-18px_rgba(40,30,10,0.75)] focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] motion-reduce:hover:[transform:translate(var(--x),var(--y))_rotate(0deg)] motion-reduce:focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)]" tabindex="0" style="--x:-40px;--y:40px;--r:4deg">
      <img class="block w-full h-37.5 object-cover" src="https://picsum.photos/seed/tw-pola-3/300/300" width="300" height="300" alt="Painted trail marker on a mountain path">
      <figcaption class="px-1 pt-3 pb-3.5 text-center font-stk12-hand text-base text-stk12-ink">Km 14</figcaption>
    </figure>
    <figure class="absolute left-1/2 top-1/2 -ml-22.5 -mt-27.5 w-45 cursor-pointer rounded-[3px] bg-white p-3 pb-0 shadow-[0_16px_30px_-14px_rgba(40,30,10,0.6)] [transform:translate(var(--x),var(--y))_rotate(var(--r))] transition-[transform,box-shadow] duration-350 ease-stk12 hover:z-10 hover:shadow-[0_30px_50px_-18px_rgba(40,30,10,0.75)] hover:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] focus-visible:z-10 focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--color-stk12-ring),0_30px_50px_-18px_rgba(40,30,10,0.75)] focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] motion-reduce:hover:[transform:translate(var(--x),var(--y))_rotate(0deg)] motion-reduce:focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)]" tabindex="0" style="--x:80px;--y:30px;--r:-5deg">
      <img class="block w-full h-37.5 object-cover" src="https://picsum.photos/seed/tw-pola-4/300/300" width="300" height="300" alt="Sun setting behind a long ridge">
      <figcaption class="px-1 pt-3 pb-3.5 text-center font-stk12-hand text-base text-stk12-ink">Golden hour</figcaption>
    </figure>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-stk12-table: #cdbfa8;
  --color-stk12-table: oklch(0.81 0.032 80);
  --color-stk12-ink: #4a4030;
  --color-stk12-ink: oklch(0.38 0.025 80);
  --color-stk12-ring: #5b78e8;
  --color-stk12-ring: oklch(0.60 0.17 262);
  --font-stk12-sans: 'Archivo', system-ui, sans-serif;
  --font-stk12-hand: 'Caveat', 'Segoe Script', cursive;
  --ease-stk12: 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-stk12-table: #cdbfa8;
  --color-stk12-table: oklch(0.81 0.032 80);
  --color-stk12-ink: #4a4030;
  --color-stk12-ink: oklch(0.38 0.025 80);
  --color-stk12-ring: #5b78e8;
  --color-stk12-ring: oklch(0.60 0.17 262);
  --font-stk12-sans: 'Archivo', system-ui, sans-serif;
  --font-stk12-hand: 'Caveat', 'Segoe Script', cursive;
  --ease-stk12: 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&family=Caveat:wght@500;600&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.
  • The handwriting face becomes a --font-* theme entry, so font-stk12-hand is applied like any other token instead of hiding in a figcaption rule.
  • The scatter is three numbers per element and one shared arbitrary transform — the same pattern as demo 03, here with rotation as the thing hover cancels rather than adds.
  • The hover state repeats the translate and zeroes only the rotate, which is what makes the snap read as lifted rather than relocated.
  • The centring maths moves from a margin:-110px 0 0 -90px shorthand to explicit -ml-22.5 -mt-27.5, which is legible next to the left-1/2 top-1/2 it corrects for.
  • Caveat replaces the CSS version's 'Bradley Hand','Segoe Script' local-font stack, so the caption looks the same on every platform rather than only on macOS.
  • The stylesheet is @theme only: two colours, a focus ring, two fonts and an easing curve.
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 Polaroid Photo Stack Scattered Rotate
Source: https://codefronts.com/components/tailwind-stacked-cards/tailwind-polaroid-photo-stack-scattered-rotate/

Snapshots tossed on a table: thick white frames, handwritten captions, deliberate mess. Each snap's position is three numbers on the element (--x, --y, --r) and hovering zeroes the rotation while raising z-10, so the one you are looking at pops clean out of the pile. The captions carry a --font-* theme entry, which is how a second typeface becomes font-stk12-hand rather than a one-off rule.
## HTML
```html
<section class="stk-12 w-full min-h-svh flex items-center justify-center px-5 py-15 font-stk12-sans bg-stk12-table" aria-label="Scattered Polaroid photos">
  <div class="relative w-[min(360px,90vw)] h-85">
    <figure class="absolute left-1/2 top-1/2 -ml-22.5 -mt-27.5 w-45 cursor-pointer rounded-[3px] bg-white p-3 pb-0 shadow-[0_16px_30px_-14px_rgba(40,30,10,0.6)] [transform:translate(var(--x),var(--y))_rotate(var(--r))] transition-[transform,box-shadow] duration-350 ease-stk12 hover:z-10 hover:shadow-[0_30px_50px_-18px_rgba(40,30,10,0.75)] hover:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] focus-visible:z-10 focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--color-stk12-ring),0_30px_50px_-18px_rgba(40,30,10,0.75)] focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] motion-reduce:hover:[transform:translate(var(--x),var(--y))_rotate(0deg)] motion-reduce:focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)]" tabindex="0" style="--x:-90px;--y:-30px;--r:-8deg">
      <img class="block w-full h-37.5 object-cover" src="https://picsum.photos/seed/tw-pola-1/300/300" width="300" height="300" alt="Tent pitched beside a lake at dawn">
      <figcaption class="px-1 pt-3 pb-3.5 text-center font-stk12-hand text-base text-stk12-ink">Dawn, day 3</figcaption>
    </figure>
    <figure class="absolute left-1/2 top-1/2 -ml-22.5 -mt-27.5 w-45 cursor-pointer rounded-[3px] bg-white p-3 pb-0 shadow-[0_16px_30px_-14px_rgba(40,30,10,0.6)] [transform:translate(var(--x),var(--y))_rotate(var(--r))] transition-[transform,box-shadow] duration-350 ease-stk12 hover:z-10 hover:shadow-[0_30px_50px_-18px_rgba(40,30,10,0.75)] hover:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] focus-visible:z-10 focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--color-stk12-ring),0_30px_50px_-18px_rgba(40,30,10,0.75)] focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] motion-reduce:hover:[transform:translate(var(--x),var(--y))_rotate(0deg)] motion-reduce:focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)]" tabindex="0" style="--x:30px;--y:-50px;--r:6deg">
      <img class="block w-full h-37.5 object-cover" src="https://picsum.photos/seed/tw-pola-2/300/300" width="300" height="300" alt="Two enamel mugs of coffee on a camp stove">
      <figcaption class="px-1 pt-3 pb-3.5 text-center font-stk12-hand text-base text-stk12-ink">First light coffee</figcaption>
    </figure>
    <figure class="absolute left-1/2 top-1/2 -ml-22.5 -mt-27.5 w-45 cursor-pointer rounded-[3px] bg-white p-3 pb-0 shadow-[0_16px_30px_-14px_rgba(40,30,10,0.6)] [transform:translate(var(--x),var(--y))_rotate(var(--r))] transition-[transform,box-shadow] duration-350 ease-stk12 hover:z-10 hover:shadow-[0_30px_50px_-18px_rgba(40,30,10,0.75)] hover:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] focus-visible:z-10 focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--color-stk12-ring),0_30px_50px_-18px_rgba(40,30,10,0.75)] focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] motion-reduce:hover:[transform:translate(var(--x),var(--y))_rotate(0deg)] motion-reduce:focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)]" tabindex="0" style="--x:-40px;--y:40px;--r:4deg">
      <img class="block w-full h-37.5 object-cover" src="https://picsum.photos/seed/tw-pola-3/300/300" width="300" height="300" alt="Painted trail marker on a mountain path">
      <figcaption class="px-1 pt-3 pb-3.5 text-center font-stk12-hand text-base text-stk12-ink">Km 14</figcaption>
    </figure>
    <figure class="absolute left-1/2 top-1/2 -ml-22.5 -mt-27.5 w-45 cursor-pointer rounded-[3px] bg-white p-3 pb-0 shadow-[0_16px_30px_-14px_rgba(40,30,10,0.6)] [transform:translate(var(--x),var(--y))_rotate(var(--r))] transition-[transform,box-shadow] duration-350 ease-stk12 hover:z-10 hover:shadow-[0_30px_50px_-18px_rgba(40,30,10,0.75)] hover:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] focus-visible:z-10 focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_var(--color-stk12-ring),0_30px_50px_-18px_rgba(40,30,10,0.75)] focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)] motion-reduce:hover:[transform:translate(var(--x),var(--y))_rotate(0deg)] motion-reduce:focus-visible:[transform:translate(var(--x),var(--y))_rotate(0deg)]" tabindex="0" style="--x:80px;--y:30px;--r:-5deg">
      <img class="block w-full h-37.5 object-cover" src="https://picsum.photos/seed/tw-pola-4/300/300" width="300" height="300" alt="Sun setting behind a long ridge">
      <figcaption class="px-1 pt-3 pb-3.5 text-center font-stk12-hand text-base text-stk12-ink">Golden hour</figcaption>
    </figure>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-stk12-table: #cdbfa8;
  --color-stk12-table: oklch(0.81 0.032 80);
  --color-stk12-ink: #4a4030;
  --color-stk12-ink: oklch(0.38 0.025 80);
  --color-stk12-ring: #5b78e8;
  --color-stk12-ring: oklch(0.60 0.17 262);
  --font-stk12-sans: 'Archivo', system-ui, sans-serif;
  --font-stk12-hand: 'Caveat', 'Segoe Script', cursive;
  --ease-stk12: cubic-bezier(0.3, 0.9, 0.3, 1);
}
```

How this works

Three numbers, one transform. Every snap declares where it landed and how crooked it is:

<figure style="--x:-90px;--y:-30px;--r:-8deg"
  class="[transform:translate(var(--x),var(--y))_rotate(var(--r))]
         hover:[transform:translate(var(--x),var(--y))_rotate(0deg)_scale(1.08)]">

The hover state keeps the position and cancels only the rotation, which is what makes the snap look picked up rather than moved.

The caption font is a token. Adding --font-stk12-hand to @theme mints a font-stk12-hand utility, so the handwritten face is applied the same way as any colour and can be swapped in one place. A one-off font-family in a rule would work and would also be the only styling in the demo not visible in the markup.

Alt text is not optional here. A scattered pile is a decorative arrangement of real content: every photo keeps meaningful alt text and a visible caption, and the mess is styling that assistive technology never sees.

Make it yours

  • Reposition a snap by editing its three numbers; nothing else in the demo knows or cares where the others are.
  • Thicken the frame with the asymmetric padding (p-3 pb-0 plus the caption's own padding) — that imbalance is what makes it read as a Polaroid.
  • Swap the caption face by changing --font-stk12-hand in @theme.
  • Change the photo crop with the image's fixed h-37.5 and object-cover.
  • Add tape or texture with a before: utility on the figure rather than a new element.

Gotchas — read before shipping

  • Keep meaningful alt text. The scatter must not become a reason for the content to disappear from the accessibility tree.
  • The hovered snap needs z-10; without it a later sibling still paints on top of the card you just straightened.
  • Give the board padding — rotated corners swing outside the unrotated box and clip against a tight parent.
  • The hover transform has to repeat translate(var(--x),var(--y)), or straightening also throws the snap back to the centre.
  • Set an explicit image height and object-cover. Intrinsic-ratio images inside a fixed frame stretch the white border unevenly.
  • Handwriting faces are often thin; keep the caption at text-base and full-strength ink so it still clears 4.5:1.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Absolute positioning, transforms and object-fit 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

Search CodeFronts

Loading…