16 / 20
All 20 in 20 Tailwind CSS Cards
- 01Tailwind E-Commerce Product Grid Card with Hover Quick-Add
- 02Tailwind SaaS Pricing Tier Card Row with Popular Plan
- 03Tailwind Recipe Card with Cook-Time Meta Grid
- 04Tailwind Real Estate Listing Card with Walk Score Rings
- 05Tailwind Hotel Booking Card with Photo Mosaic & Price Breakdown
- 06Tailwind Blog Index Card Stack with Split Hero
- 07Tailwind Horizontal Article Card Feed with Ranked Covers
- 08Tailwind Testimonial Card with Sentiment Strip
- 09Tailwind Video Preview Card with Glass Play Button
- 10Tailwind Leaderboard Card with Gradient Medal Ranks
- 11Tailwind Team Profile Card with Masked Grid Cover
- 12Tailwind SaaS Feature Card with Arrow-Slide Link
- 13Tailwind Dark vCard with Iridescent Sheen
- 14Tailwind Portfolio Card with CSS-Drawn Dashboard Mock
- 15Tailwind Dark KPI Stat Card with SVG Sparkline
- 16Tailwind 3D Flip Business Card with Keyboard Reveal
- 17Tailwind Glassmorphism Card on Animated Aurora Stage
- 18Tailwind Rotating Conic-Border Card with Terminal Panel
- 19Tailwind 3D Pop-Out Product Card with translateZ Lift
- 20Tailwind Stacked Card Cascade with Focus-Within Fan-Out
Tailwind 3D Flip Business Card with Keyboard Reveal
A gilt-on-navy calling card that turns on hover and focus-within, so the contact details on the back are reachable by keyboard. The port's win is the reduced-motion path: instead of cancelling the flip and hiding the back face forever, it becomes an opacity crossfade — same information, no spatial motion.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="twc-16 w-full min-h-svh flex items-center justify-center px-5 py-9 bg-twc16-bg [background-image:radial-gradient(ellipse_at_30%_20%,#1e293b_0%,transparent_60%),radial-gradient(ellipse_at_80%_80%,#0f172a_0%,transparent_60%)] font-twc16-sans">
<div tabindex="0" aria-label="Business card for Alex Chen — reveals contact details" class="group w-90 h-55 max-[420px]:w-full max-[420px]:max-w-[360px] rounded-[14px] [perspective:1000px] focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-6">
<div class="relative size-full [transform-style:preserve-3d] transition-transform duration-700 ease-[cubic-bezier(0.34,1.2,0.64,1)] group-hover:[transform:rotateY(180deg)] group-focus-within:[transform:rotateY(180deg)] shadow-[0_30px_60px_-12px_oklch(0_0_0/0.6),0_18px_36px_-18px_oklch(0.75_0.1_85/0.35)] motion-reduce:transition-none motion-reduce:group-hover:[transform:none] motion-reduce:group-focus-within:[transform:none]">
<div class="absolute inset-0 flex flex-col justify-between overflow-hidden rounded-[14px] px-7 py-6.5 border border-twc16-gilt/28 [backface-visibility:hidden] [-webkit-backface-visibility:hidden] [background:linear-gradient(135deg,oklch(0.75_0.1_85/0.14)_0%,transparent_40%,transparent_60%,oklch(0.75_0.1_85/0.06)_100%),linear-gradient(160deg,#16213e_0%,#0f172a_50%,#050815_100%)] before:absolute before:top-0 before:right-0 before:w-3/5 before:h-3/5 before:pointer-events-none before:content-[''] before:[background:radial-gradient(circle_at_top_right,oklch(0.87_0.11_90/0.18),transparent_60%)]">
<div aria-hidden="true" class="flex items-center gap-2.5">
<span class="relative size-8 rounded-full [background:linear-gradient(135deg,#f5d97b_0%,#d4b063_50%,#9a7a3d_100%)] shadow-[inset_0_-2px_4px_oklch(0_0_0/0.25),inset_0_2px_4px_oklch(1_0_0/0.3),0_2px_6px_oklch(0.75_0.1_85/0.35)] before:absolute before:inset-2 before:rounded-full before:content-[''] before:[background:linear-gradient(135deg,#050815,#16213e)] after:absolute after:inset-0 after:flex after:items-center after:justify-center after:content-['A'] after:font-twc16-serif after:text-[15px] after:font-bold after:text-twc16-giltlite after:[text-shadow:0_1px_2px_oklch(0_0_0/0.6)]"></span>
<span class="font-twc16-serif text-[11px] font-semibold tracking-[0.24em] uppercase text-twc16-gilt">CHEN & CO</span>
</div>
<div class="mb-3">
<h3 class="m-0 mb-1 font-twc16-serif text-[26px]/[1.1] font-bold tracking-[-0.005em] text-twc16-ink">Alex Chen</h3>
<p class="m-0 text-[11px] font-medium tracking-[0.14em] uppercase text-twc16-giltlite/85">Principal Designer</p>
</div>
<span class="self-end text-[9.5px] tracking-[0.14em] uppercase text-twc16-faint">Hover or tab to flip</span>
</div>
<div class="absolute inset-0 flex flex-col justify-between overflow-hidden rounded-[14px] px-7 py-6.5 border border-twc16-gilt/28 [transform:rotateY(180deg)] [backface-visibility:hidden] [-webkit-backface-visibility:hidden] [background:linear-gradient(135deg,oklch(0.75_0.1_85/0.14)_0%,transparent_40%,transparent_60%,oklch(0.75_0.1_85/0.06)_100%),linear-gradient(160deg,#16213e_0%,#0f172a_50%,#050815_100%)] motion-reduce:[transform:none] motion-reduce:[backface-visibility:visible] motion-reduce:opacity-0 motion-reduce:transition-opacity motion-reduce:duration-200 motion-reduce:group-hover:opacity-100 motion-reduce:group-focus-within:opacity-100">
<span class="font-twc16-serif text-[10.5px] font-semibold tracking-[0.28em] uppercase text-twc16-gilt/75">CHEN & CO</span>
<address class="flex flex-col not-italic">
<div class="flex items-center gap-3 min-h-11 border-b border-twc16-gilt/15">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
<a href="mailto:alex@chen.co" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">alex@chen.co</a>
</div>
<div class="flex items-center gap-3 min-h-11 border-b border-twc16-gilt/15">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
<a href="tel:+14155550142" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">+1 (415) 555-0142</a>
</div>
<div class="flex items-center gap-3 min-h-11">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
<a href="#site" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">alexchen.design</a>
</div>
</address>
</div>
</div>
</div>
</section><section class="twc-16 w-full min-h-svh flex items-center justify-center px-5 py-9 bg-twc16-bg [background-image:radial-gradient(ellipse_at_30%_20%,#1e293b_0%,transparent_60%),radial-gradient(ellipse_at_80%_80%,#0f172a_0%,transparent_60%)] font-twc16-sans">
<div tabindex="0" aria-label="Business card for Alex Chen — reveals contact details" class="group w-90 h-55 max-[420px]:w-full max-[420px]:max-w-[360px] rounded-[14px] [perspective:1000px] focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-6">
<div class="relative size-full [transform-style:preserve-3d] transition-transform duration-700 ease-[cubic-bezier(0.34,1.2,0.64,1)] group-hover:[transform:rotateY(180deg)] group-focus-within:[transform:rotateY(180deg)] shadow-[0_30px_60px_-12px_oklch(0_0_0/0.6),0_18px_36px_-18px_oklch(0.75_0.1_85/0.35)] motion-reduce:transition-none motion-reduce:group-hover:[transform:none] motion-reduce:group-focus-within:[transform:none]">
<div class="absolute inset-0 flex flex-col justify-between overflow-hidden rounded-[14px] px-7 py-6.5 border border-twc16-gilt/28 [backface-visibility:hidden] [-webkit-backface-visibility:hidden] [background:linear-gradient(135deg,oklch(0.75_0.1_85/0.14)_0%,transparent_40%,transparent_60%,oklch(0.75_0.1_85/0.06)_100%),linear-gradient(160deg,#16213e_0%,#0f172a_50%,#050815_100%)] before:absolute before:top-0 before:right-0 before:w-3/5 before:h-3/5 before:pointer-events-none before:content-[''] before:[background:radial-gradient(circle_at_top_right,oklch(0.87_0.11_90/0.18),transparent_60%)]">
<div aria-hidden="true" class="flex items-center gap-2.5">
<span class="relative size-8 rounded-full [background:linear-gradient(135deg,#f5d97b_0%,#d4b063_50%,#9a7a3d_100%)] shadow-[inset_0_-2px_4px_oklch(0_0_0/0.25),inset_0_2px_4px_oklch(1_0_0/0.3),0_2px_6px_oklch(0.75_0.1_85/0.35)] before:absolute before:inset-2 before:rounded-full before:content-[''] before:[background:linear-gradient(135deg,#050815,#16213e)] after:absolute after:inset-0 after:flex after:items-center after:justify-center after:content-['A'] after:font-twc16-serif after:text-[15px] after:font-bold after:text-twc16-giltlite after:[text-shadow:0_1px_2px_oklch(0_0_0/0.6)]"></span>
<span class="font-twc16-serif text-[11px] font-semibold tracking-[0.24em] uppercase text-twc16-gilt">CHEN & CO</span>
</div>
<div class="mb-3">
<h3 class="m-0 mb-1 font-twc16-serif text-[26px]/[1.1] font-bold tracking-[-0.005em] text-twc16-ink">Alex Chen</h3>
<p class="m-0 text-[11px] font-medium tracking-[0.14em] uppercase text-twc16-giltlite/85">Principal Designer</p>
</div>
<span class="self-end text-[9.5px] tracking-[0.14em] uppercase text-twc16-faint">Hover or tab to flip</span>
</div>
<div class="absolute inset-0 flex flex-col justify-between overflow-hidden rounded-[14px] px-7 py-6.5 border border-twc16-gilt/28 [transform:rotateY(180deg)] [backface-visibility:hidden] [-webkit-backface-visibility:hidden] [background:linear-gradient(135deg,oklch(0.75_0.1_85/0.14)_0%,transparent_40%,transparent_60%,oklch(0.75_0.1_85/0.06)_100%),linear-gradient(160deg,#16213e_0%,#0f172a_50%,#050815_100%)] motion-reduce:[transform:none] motion-reduce:[backface-visibility:visible] motion-reduce:opacity-0 motion-reduce:transition-opacity motion-reduce:duration-200 motion-reduce:group-hover:opacity-100 motion-reduce:group-focus-within:opacity-100">
<span class="font-twc16-serif text-[10.5px] font-semibold tracking-[0.28em] uppercase text-twc16-gilt/75">CHEN & CO</span>
<address class="flex flex-col not-italic">
<div class="flex items-center gap-3 min-h-11 border-b border-twc16-gilt/15">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
<a href="mailto:alex@chen.co" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">alex@chen.co</a>
</div>
<div class="flex items-center gap-3 min-h-11 border-b border-twc16-gilt/15">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
<a href="tel:+14155550142" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">+1 (415) 555-0142</a>
</div>
<div class="flex items-center gap-3 min-h-11">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
<a href="#site" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">alexchen.design</a>
</div>
</address>
</div>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-twc16-bg: #050815;
--color-twc16-bg: oklch(0.13 0.03 265);
--color-twc16-ink: #f8fafc;
--color-twc16-ink: oklch(0.98 0.005 250);
--color-twc16-ink2: #e2e8f0;
--color-twc16-ink2: oklch(0.92 0.01 250);
--color-twc16-faint: #94a3b8;
--color-twc16-faint: oklch(0.7 0.03 250);
--color-twc16-gilt: #d4b063;
--color-twc16-gilt: oklch(0.75 0.1 85);
--color-twc16-giltlite: #f5d97b;
--color-twc16-giltlite: oklch(0.87 0.11 90);
--font-twc16-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc16-serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
}
/* 3D transform properties, backface hiding and perspective have no utilities
and should not: they are structural, not design-scale. They ship as
arbitrary properties in the markup. */
.twc-16 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-twc16-bg: #050815;
--color-twc16-bg: oklch(0.13 0.03 265);
--color-twc16-ink: #f8fafc;
--color-twc16-ink: oklch(0.98 0.005 250);
--color-twc16-ink2: #e2e8f0;
--color-twc16-ink2: oklch(0.92 0.01 250);
--color-twc16-faint: #94a3b8;
--color-twc16-faint: oklch(0.7 0.03 250);
--color-twc16-gilt: #d4b063;
--color-twc16-gilt: oklch(0.75 0.1 85);
--color-twc16-giltlite: #f5d97b;
--color-twc16-giltlite: oklch(0.87 0.11 90);
--font-twc16-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc16-serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
}
/* 3D transform properties, backface hiding and perspective have no utilities
and should not: they are structural, not design-scale. They ship as
arbitrary properties in the markup. */
.twc-16 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<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.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-twc16-bg: #050815;
--color-twc16-bg: oklch(0.13 0.03 265);
--color-twc16-ink: #f8fafc;
--color-twc16-ink: oklch(0.98 0.005 250);
--color-twc16-ink2: #e2e8f0;
--color-twc16-ink2: oklch(0.92 0.01 250);
--color-twc16-faint: #94a3b8;
--color-twc16-faint: oklch(0.7 0.03 250);
--color-twc16-gilt: #d4b063;
--color-twc16-gilt: oklch(0.75 0.1 85);
--color-twc16-giltlite: #f5d97b;
--color-twc16-giltlite: oklch(0.87 0.11 90);
--font-twc16-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc16-serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
}
/* 3D transform properties, backface hiding and perspective have no utilities
and should not: they are structural, not design-scale. They ship as
arbitrary properties in the markup. */
.twc-16 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-twc16-bg: #050815;
--color-twc16-bg: oklch(0.13 0.03 265);
--color-twc16-ink: #f8fafc;
--color-twc16-ink: oklch(0.98 0.005 250);
--color-twc16-ink2: #e2e8f0;
--color-twc16-ink2: oklch(0.92 0.01 250);
--color-twc16-faint: #94a3b8;
--color-twc16-faint: oklch(0.7 0.03 250);
--color-twc16-gilt: #d4b063;
--color-twc16-gilt: oklch(0.75 0.1 85);
--color-twc16-giltlite: #f5d97b;
--color-twc16-giltlite: oklch(0.87 0.11 90);
--font-twc16-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc16-serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
}
/* 3D transform properties, backface hiding and perspective have no utilities
and should not: they are structural, not design-scale. They ship as
arbitrary properties in the markup. */
.twc-16 {
width: 100%;
min-height: 100svh;
}<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=Space+Grotesk:wght@400;500;600;700&family=Cormorant+Garamond:wght@600;700&display=swap">
<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=Space+Grotesk:wght@400;500;600;700&family=Cormorant+Garamond:wght@600;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The flip's two triggers collapse into two variants on one element. In CSS they were a comma-joined selector pair; as
group-hover:andgroup-focus-within:they sit in the class list of the thing that rotates. - The reduced-motion branch is the substantive improvement. The CSS original cancelled the rotation, which left the back face hidden behind
backface-visibility— the contact details became unreachable for exactly the users who set the preference. The crossfade keeps them. - The monogram stays a pseudo-element pair (
before:disc,after:content-['A']) because an inlay is what pseudo-elements are for; the variant syntax keeps it visible at the element. - UI change from the CSS original: the hint copy now says “Hover or tab to flip” (the keyboard path existed but was undocumented to the user), the card goes fluid under 420px instead of staying a fixed 360px, and the serif stack moved to Cormorant Garamond with a Georgia fallback.
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 3D Flip Business Card with Keyboard Reveal
Source: https://codefronts.com/components/tailwind-css-cards/tailwind-3d-flip-business-card-keyboard-reveal/
A gilt-on-navy calling card that turns on hover and focus-within, so the contact details on the back are reachable by keyboard. The port's win is the reduced-motion path: instead of cancelling the flip and hiding the back face forever, it becomes an opacity crossfade — same information, no spatial motion.
## HTML
```html
<section class="twc-16 w-full min-h-svh flex items-center justify-center px-5 py-9 bg-twc16-bg [background-image:radial-gradient(ellipse_at_30%_20%,#1e293b_0%,transparent_60%),radial-gradient(ellipse_at_80%_80%,#0f172a_0%,transparent_60%)] font-twc16-sans">
<div tabindex="0" aria-label="Business card for Alex Chen — reveals contact details" class="group w-90 h-55 max-[420px]:w-full max-[420px]:max-w-[360px] rounded-[14px] [perspective:1000px] focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-6">
<div class="relative size-full [transform-style:preserve-3d] transition-transform duration-700 ease-[cubic-bezier(0.34,1.2,0.64,1)] group-hover:[transform:rotateY(180deg)] group-focus-within:[transform:rotateY(180deg)] shadow-[0_30px_60px_-12px_oklch(0_0_0/0.6),0_18px_36px_-18px_oklch(0.75_0.1_85/0.35)] motion-reduce:transition-none motion-reduce:group-hover:[transform:none] motion-reduce:group-focus-within:[transform:none]">
<div class="absolute inset-0 flex flex-col justify-between overflow-hidden rounded-[14px] px-7 py-6.5 border border-twc16-gilt/28 [backface-visibility:hidden] [-webkit-backface-visibility:hidden] [background:linear-gradient(135deg,oklch(0.75_0.1_85/0.14)_0%,transparent_40%,transparent_60%,oklch(0.75_0.1_85/0.06)_100%),linear-gradient(160deg,#16213e_0%,#0f172a_50%,#050815_100%)] before:absolute before:top-0 before:right-0 before:w-3/5 before:h-3/5 before:pointer-events-none before:content-[''] before:[background:radial-gradient(circle_at_top_right,oklch(0.87_0.11_90/0.18),transparent_60%)]">
<div aria-hidden="true" class="flex items-center gap-2.5">
<span class="relative size-8 rounded-full [background:linear-gradient(135deg,#f5d97b_0%,#d4b063_50%,#9a7a3d_100%)] shadow-[inset_0_-2px_4px_oklch(0_0_0/0.25),inset_0_2px_4px_oklch(1_0_0/0.3),0_2px_6px_oklch(0.75_0.1_85/0.35)] before:absolute before:inset-2 before:rounded-full before:content-[''] before:[background:linear-gradient(135deg,#050815,#16213e)] after:absolute after:inset-0 after:flex after:items-center after:justify-center after:content-['A'] after:font-twc16-serif after:text-[15px] after:font-bold after:text-twc16-giltlite after:[text-shadow:0_1px_2px_oklch(0_0_0/0.6)]"></span>
<span class="font-twc16-serif text-[11px] font-semibold tracking-[0.24em] uppercase text-twc16-gilt">CHEN & CO</span>
</div>
<div class="mb-3">
<h3 class="m-0 mb-1 font-twc16-serif text-[26px]/[1.1] font-bold tracking-[-0.005em] text-twc16-ink">Alex Chen</h3>
<p class="m-0 text-[11px] font-medium tracking-[0.14em] uppercase text-twc16-giltlite/85">Principal Designer</p>
</div>
<span class="self-end text-[9.5px] tracking-[0.14em] uppercase text-twc16-faint">Hover or tab to flip</span>
</div>
<div class="absolute inset-0 flex flex-col justify-between overflow-hidden rounded-[14px] px-7 py-6.5 border border-twc16-gilt/28 [transform:rotateY(180deg)] [backface-visibility:hidden] [-webkit-backface-visibility:hidden] [background:linear-gradient(135deg,oklch(0.75_0.1_85/0.14)_0%,transparent_40%,transparent_60%,oklch(0.75_0.1_85/0.06)_100%),linear-gradient(160deg,#16213e_0%,#0f172a_50%,#050815_100%)] motion-reduce:[transform:none] motion-reduce:[backface-visibility:visible] motion-reduce:opacity-0 motion-reduce:transition-opacity motion-reduce:duration-200 motion-reduce:group-hover:opacity-100 motion-reduce:group-focus-within:opacity-100">
<span class="font-twc16-serif text-[10.5px] font-semibold tracking-[0.28em] uppercase text-twc16-gilt/75">CHEN & CO</span>
<address class="flex flex-col not-italic">
<div class="flex items-center gap-3 min-h-11 border-b border-twc16-gilt/15">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
<a href="mailto:alex@chen.co" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">alex@chen.co</a>
</div>
<div class="flex items-center gap-3 min-h-11 border-b border-twc16-gilt/15">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
<a href="tel:+14155550142" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">+1 (415) 555-0142</a>
</div>
<div class="flex items-center gap-3 min-h-11">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
<a href="#site" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">alexchen.design</a>
</div>
</address>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-twc16-bg: #050815;
--color-twc16-bg: oklch(0.13 0.03 265);
--color-twc16-ink: #f8fafc;
--color-twc16-ink: oklch(0.98 0.005 250);
--color-twc16-ink2: #e2e8f0;
--color-twc16-ink2: oklch(0.92 0.01 250);
--color-twc16-faint: #94a3b8;
--color-twc16-faint: oklch(0.7 0.03 250);
--color-twc16-gilt: #d4b063;
--color-twc16-gilt: oklch(0.75 0.1 85);
--color-twc16-giltlite: #f5d97b;
--color-twc16-giltlite: oklch(0.87 0.11 90);
--font-twc16-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc16-serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
}
/* 3D transform properties, backface hiding and perspective have no utilities
and should not: they are structural, not design-scale. They ship as
arbitrary properties in the markup. */
.twc-16 {
width: 100%;
min-height: 100svh;
}
```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 3D Flip Business Card with Keyboard Reveal
Source: https://codefronts.com/components/tailwind-css-cards/tailwind-3d-flip-business-card-keyboard-reveal/
A gilt-on-navy calling card that turns on hover and focus-within, so the contact details on the back are reachable by keyboard. The port's win is the reduced-motion path: instead of cancelling the flip and hiding the back face forever, it becomes an opacity crossfade — same information, no spatial motion.
## HTML
```html
<section class="twc-16 w-full min-h-svh flex items-center justify-center px-5 py-9 bg-twc16-bg [background-image:radial-gradient(ellipse_at_30%_20%,#1e293b_0%,transparent_60%),radial-gradient(ellipse_at_80%_80%,#0f172a_0%,transparent_60%)] font-twc16-sans">
<div tabindex="0" aria-label="Business card for Alex Chen — reveals contact details" class="group w-90 h-55 max-[420px]:w-full max-[420px]:max-w-[360px] rounded-[14px] [perspective:1000px] focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-6">
<div class="relative size-full [transform-style:preserve-3d] transition-transform duration-700 ease-[cubic-bezier(0.34,1.2,0.64,1)] group-hover:[transform:rotateY(180deg)] group-focus-within:[transform:rotateY(180deg)] shadow-[0_30px_60px_-12px_oklch(0_0_0/0.6),0_18px_36px_-18px_oklch(0.75_0.1_85/0.35)] motion-reduce:transition-none motion-reduce:group-hover:[transform:none] motion-reduce:group-focus-within:[transform:none]">
<div class="absolute inset-0 flex flex-col justify-between overflow-hidden rounded-[14px] px-7 py-6.5 border border-twc16-gilt/28 [backface-visibility:hidden] [-webkit-backface-visibility:hidden] [background:linear-gradient(135deg,oklch(0.75_0.1_85/0.14)_0%,transparent_40%,transparent_60%,oklch(0.75_0.1_85/0.06)_100%),linear-gradient(160deg,#16213e_0%,#0f172a_50%,#050815_100%)] before:absolute before:top-0 before:right-0 before:w-3/5 before:h-3/5 before:pointer-events-none before:content-[''] before:[background:radial-gradient(circle_at_top_right,oklch(0.87_0.11_90/0.18),transparent_60%)]">
<div aria-hidden="true" class="flex items-center gap-2.5">
<span class="relative size-8 rounded-full [background:linear-gradient(135deg,#f5d97b_0%,#d4b063_50%,#9a7a3d_100%)] shadow-[inset_0_-2px_4px_oklch(0_0_0/0.25),inset_0_2px_4px_oklch(1_0_0/0.3),0_2px_6px_oklch(0.75_0.1_85/0.35)] before:absolute before:inset-2 before:rounded-full before:content-[''] before:[background:linear-gradient(135deg,#050815,#16213e)] after:absolute after:inset-0 after:flex after:items-center after:justify-center after:content-['A'] after:font-twc16-serif after:text-[15px] after:font-bold after:text-twc16-giltlite after:[text-shadow:0_1px_2px_oklch(0_0_0/0.6)]"></span>
<span class="font-twc16-serif text-[11px] font-semibold tracking-[0.24em] uppercase text-twc16-gilt">CHEN & CO</span>
</div>
<div class="mb-3">
<h3 class="m-0 mb-1 font-twc16-serif text-[26px]/[1.1] font-bold tracking-[-0.005em] text-twc16-ink">Alex Chen</h3>
<p class="m-0 text-[11px] font-medium tracking-[0.14em] uppercase text-twc16-giltlite/85">Principal Designer</p>
</div>
<span class="self-end text-[9.5px] tracking-[0.14em] uppercase text-twc16-faint">Hover or tab to flip</span>
</div>
<div class="absolute inset-0 flex flex-col justify-between overflow-hidden rounded-[14px] px-7 py-6.5 border border-twc16-gilt/28 [transform:rotateY(180deg)] [backface-visibility:hidden] [-webkit-backface-visibility:hidden] [background:linear-gradient(135deg,oklch(0.75_0.1_85/0.14)_0%,transparent_40%,transparent_60%,oklch(0.75_0.1_85/0.06)_100%),linear-gradient(160deg,#16213e_0%,#0f172a_50%,#050815_100%)] motion-reduce:[transform:none] motion-reduce:[backface-visibility:visible] motion-reduce:opacity-0 motion-reduce:transition-opacity motion-reduce:duration-200 motion-reduce:group-hover:opacity-100 motion-reduce:group-focus-within:opacity-100">
<span class="font-twc16-serif text-[10.5px] font-semibold tracking-[0.28em] uppercase text-twc16-gilt/75">CHEN & CO</span>
<address class="flex flex-col not-italic">
<div class="flex items-center gap-3 min-h-11 border-b border-twc16-gilt/15">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
<a href="mailto:alex@chen.co" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">alex@chen.co</a>
</div>
<div class="flex items-center gap-3 min-h-11 border-b border-twc16-gilt/15">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
<a href="tel:+14155550142" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">+1 (415) 555-0142</a>
</div>
<div class="flex items-center gap-3 min-h-11">
<svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="flex-none text-twc16-gilt"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
<a href="#site" class="text-[13px] font-medium tracking-[0.01em] text-twc16-ink2 no-underline transition-colors duration-200 hover:text-twc16-giltlite focus-visible:outline-2 focus-visible:outline-twc16-gilt focus-visible:outline-offset-2">alexchen.design</a>
</div>
</address>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-twc16-bg: #050815;
--color-twc16-bg: oklch(0.13 0.03 265);
--color-twc16-ink: #f8fafc;
--color-twc16-ink: oklch(0.98 0.005 250);
--color-twc16-ink2: #e2e8f0;
--color-twc16-ink2: oklch(0.92 0.01 250);
--color-twc16-faint: #94a3b8;
--color-twc16-faint: oklch(0.7 0.03 250);
--color-twc16-gilt: #d4b063;
--color-twc16-gilt: oklch(0.75 0.1 85);
--color-twc16-giltlite: #f5d97b;
--color-twc16-giltlite: oklch(0.87 0.11 90);
--font-twc16-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc16-serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
}
/* 3D transform properties, backface hiding and perspective have no utilities
and should not: they are structural, not design-scale. They ship as
arbitrary properties in the markup. */
.twc-16 {
width: 100%;
min-height: 100svh;
}
```How this works
Two triggers, one transform. The reveal must work for a pointer and for a tab key, so both variants set the same rotation:
class="… transition-transform duration-700
ease-[cubic-bezier(0.34,1.2,0.64,1)]
group-hover:[transform:rotateY(180deg)]
group-focus-within:[transform:rotateY(180deg)]"Reduced motion keeps the information. Cancelling rotateY alone would leave the back face permanently hidden behind backface-visibility — the contact details would simply be unreachable. So under motion-reduce the faces stop rotating, backface hiding is switched off, and the back crossfades over the front:
motion-reduce:[transform:none]
motion-reduce:[backface-visibility:visible]
motion-reduce:opacity-0
motion-reduce:group-hover:opacity-100That is the difference between honouring the preference and breaking the component for the people who set it.
The medallion is two pseudo-elements. An inset dark disc (before:) and the serif initial (after:content-['A']) over a gold gradient ring — a monogram with no image and no extra element.
Make it yours
- Face colour: the two-layer
[background:…]on.face. Slate for fintech, espresso for hospitality — gilt stays AA on all three. - Flip feel:
duration-700with the overshoot curve reads ceremonial;duration-500 ease-outreads snappy. - Portrait: swap
w-90 h-55forw-55 h-90and let the back face stack in one column. - Replace the monogram with an inline SVG logo at 28px; keep the gold ring so the mark reads as etched rather than pasted.
Gotchas — read before shipping
-webkit-backface-visibilityis still required on iOS 16 and older, or the reversed face ghosts through mid-flip. Tailwind emits only what you write, so both spellings ship.- Never gate the reveal on hover alone.
group-focus-within:is what keeps the back-face links reachable — WCAG 2.1.1 and 2.4.7. - Under
motion-reduce, cancelling the rotation without also unhiding the backface hides the contact details permanently. The crossfade branch is mandatory, not polish. - Keep the gilt tracking loose.
#f5d97bon navy measures ~10.8:1 at 10px caps, but tightening belowtracking-[0.18em]collapses the stroke gaps in practice. - Each flipped card is its own compositor layer. On a directory page add
[content-visibility:auto] [contain-intrinsic-size:220px_360px]to off-screen cards.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
3D transforms and backface-visibility are universally supported (Safari needs the -webkit- prefix before 15.4); :focus-within has been Baseline since 2019. The floor is Tailwind v4's generated sheet.