shadcn/ui's Card component provides a solid foundation for every card layout. These 5 examples cover the most common patterns — basic, stats, profile, pricing and hover effects.
Installation
npx shadcn@latest add card badge button
npm install lucide-react
Card Anatomy
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
<CardDescription>Subtitle or description</CardDescription>
</CardHeader>
<CardContent>Main content area</CardContent>
<CardFooter>Footer actions</CardFooter>
</Card>
Key Tailwind Classes for Cards
| Class | What It Does |
|---|---|
shadow-sm | Subtle card shadow |
hover:shadow-xl | Shadow on hover |
hover:-translate-y-1.5 | Lift effect on hover |
transition-all duration-300 | Smooth animations |
overflow-hidden | Clips image zoom to card |
group | Enables group-hover children |
1. Basic shadcn/ui Card
The standard shadcn/ui Card with CardHeader, CardContent and CardFooter.
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
export default function BasicCard() {
return (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 max-w-2xl">
{/* Simple card */}
<Card>
<CardHeader>
<CardTitle>Marvel Angular Dashboard</CardTitle>
<CardDescription>Angular 21 + Bootstrap 5 admin template</CardDescription>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">
50+ components, dark mode, RTL support and 4 layout variants included.
</p>
</CardContent>
<CardFooter className="flex justify-between items-center">
<span className="font-bold text-lg" style={{ color: "#fd4766" }}>$29</span>
<Button size="sm" style={{ background: "#fd4766" }}>Buy Now</Button>
</CardFooter>
</Card>
{/* Card with badge */}
<Card>
<CardHeader>
<div className="flex justify-between items-start">
<div>
<CardTitle>PORTO Bootstrap 5</CardTitle>
<CardDescription>Multipurpose Bootstrap template</CardDescription>
</div>
<Badge style={{ background: "#fd4766" }}>Best Seller</Badge>
</div>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">
152 sales, 5.0 rating. Clean design with extensive documentation.
</p>
</CardContent>
<CardFooter className="flex justify-between items-center">
<span className="font-bold text-lg" style={{ color: "#fd4766" }}>$19</span>
<Button variant="outline" size="sm">Preview</Button>
</CardFooter>
</Card>
</div>
)
}2. React Stats Card
Dashboard metric cards with trend indicators using shadcn/ui and Lucide icons.
import { Card, CardContent } from "@/components/ui/card"
import { TrendingUp, TrendingDown, Users, DollarSign, Download, Star } from "lucide-react"
const stats = [
{
title: "Total Revenue",
value: "$12,480",
change: "+8.2%",
trend: "up",
icon: DollarSign,
color: "#10b981",
},
{
title: "Downloads",
value: "3,240",
change: "-2.4%",
trend: "down",
icon: Download,
color: "#fd4766",
},
{
title: "Active Users",
value: "1,847",
change: "+12.5%",
trend: "up",
icon: Users,
color: "#4f6ef7",
},
{
title: "Avg Rating",
value: "4.9",
change: "+0.1",
trend: "up",
icon: Star,
color: "#f59e0b",
},
]
export default function StatsCards() {
return (
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
{stats.map((stat) => {
const Icon = stat.icon
const TrendIcon = stat.trend === "up" ? TrendingUp : TrendingDown
return (
<Card key={stat.title} className="border-0 shadow-sm">
<CardContent className="p-4">
<div className="flex justify-between items-start mb-3">
<p className="text-sm text-muted-foreground">{stat.title}</p>
<div
className="w-9 h-9 rounded-lg flex items-center justify-center"
style={{ background: stat.color + "18" }}
>
<Icon size={18} style={{ color: stat.color }} />
</div>
</div>
<p className="text-2xl font-bold">{stat.value}</p>
<div className="flex items-center gap-1 mt-1">
<TrendIcon
size={14}
className={stat.trend === "up" ? "text-green-500" : "text-red-500"}
/>
<span
className="text-xs font-medium"
style={{ color: stat.trend === "up" ? "#10b981" : "#ef4444" }}
>
{stat.change}
</span>
<span className="text-xs text-muted-foreground">vs last month</span>
</div>
</CardContent>
</Card>
)
})}
</div>
)
}3. React Profile Card
User profile card with avatar, bio, stats and action buttons.
import { Card, CardContent } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { MapPin, Link2, Twitter } from "lucide-react"
export default function ProfileCard() {
return (
<Card className="border-0 shadow-sm max-w-sm overflow-hidden">
{/* Cover */}
<div
className="h-24"
style={{ background: "linear-gradient(135deg, #fd4766, #4f6ef7)" }}
/>
<CardContent className="p-4 pt-0">
{/* Avatar */}
<div
className="w-16 h-16 rounded-full border-4 border-white flex items-center justify-content-center text-white font-bold text-lg shadow-sm"
style={{ background: "#fd4766", marginTop: "-32px" }}
>
GS
</div>
<div className="mt-3">
<h3 className="font-bold text-lg">Gagan Singh</h3>
<p className="text-muted-foreground text-sm">Founder @ LettStart Design</p>
<p className="text-sm mt-2 text-gray-600">
Building Angular + Bootstrap admin templates. 10+ years of frontend experience.
</p>
<div className="flex gap-3 mt-3 text-xs text-muted-foreground">
<div className="flex items-center gap-1">
<MapPin size={12} /> India
</div>
<div className="flex items-center gap-1">
<Link2 size={12} />
<a href="https://lettstartdesign.com" className="hover:underline" style={{ color: "#fd4766" }}>
lettstartdesign.com
</a>
</div>
</div>
<div className="flex gap-4 mt-4 py-3 border-y">
{[
{ label: "Templates", value: "48" },
{ label: "Followers", value: "1.2K" },
{ label: "Sales", value: "5K+" },
].map((s) => (
<div key={s.label} className="text-center flex-1">
<p className="font-bold text-sm">{s.value}</p>
<p className="text-xs text-muted-foreground">{s.label}</p>
</div>
))}
</div>
<div className="flex gap-2 mt-4">
<Button className="flex-1" style={{ background: "#fd4766" }}>Follow</Button>
<Button variant="outline" size="icon">
<Twitter size={16} />
</Button>
</div>
</div>
</CardContent>
</Card>
)
}4. React Pricing Card
Pricing plan cards with featured plan highlight and feature lists.
import { Card, CardContent, CardHeader } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Check } from "lucide-react"
const plans = [
{
name: "Free",
price: "$0",
desc: "For individuals",
features: ["5 projects", "1GB storage", "Community support"],
missing: ["Custom domain", "Analytics"],
cta: "Get Started",
featured: false,
},
{
name: "Pro",
price: "$29",
desc: "For professionals",
features: ["50 projects", "50GB storage", "Priority support", "Custom domain", "Analytics"],
missing: [],
cta: "Start Pro Trial",
featured: true,
},
{
name: "Team",
price: "$99",
desc: "For teams",
features: ["Unlimited projects", "500GB storage", "Dedicated support", "Custom domain", "Advanced analytics"],
missing: [],
cta: "Contact Sales",
featured: false,
},
]
export default function PricingCards() {
return (
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 max-w-4xl">
{plans.map((plan) => (
<Card
key={plan.name}
className={`relative ${plan.featured ? "border-2 shadow-lg" : "border shadow-sm"}`}
style={plan.featured ? { borderColor: "#fd4766" } : {}}
>
{plan.featured && (
<div
className="absolute -top-3 left-1/2 -translate-x-1/2 px-3 py-1 text-white text-xs font-semibold rounded-full"
style={{ background: "#fd4766" }}
>
Most Popular
</div>
)}
<CardHeader className="pb-4">
<h3 className="font-bold text-lg">{plan.name}</h3>
<p className="text-sm text-muted-foreground">{plan.desc}</p>
<div className="mt-2">
<span className="text-3xl font-bold" style={{ color: plan.featured ? "#fd4766" : undefined }}>
{plan.price}
</span>
<span className="text-sm text-muted-foreground">/mo</span>
</div>
</CardHeader>
<CardContent>
<ul className="space-y-2 mb-6">
{plan.features.map((f) => (
<li key={f} className="flex items-center gap-2 text-sm">
<Check size={14} className="text-green-500 flex-shrink-0" /> {f}
</li>
))}
{plan.missing.map((f) => (
<li key={f} className="flex items-center gap-2 text-sm text-muted-foreground">
<span className="w-3.5 text-center text-xs">✕</span> {f}
</li>
))}
</ul>
<Button
className="w-full"
variant={plan.featured ? "default" : "outline"}
style={plan.featured ? { background: "#fd4766", border: "none" } : {}}
>
{plan.cta}
</Button>
</CardContent>
</Card>
))}
</div>
)
}5. React Hover Card with Tailwind Animation
Interactive card with lift effect, image zoom on hover and overlay reveal.
import { Card } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { ExternalLink } from "lucide-react"
const templates = [
{
name: "Marvel Angular Dashboard",
framework: "Angular 21",
price: "$29",
badge: "Best Seller",
color: "#fd4766",
image: "https://picsum.photos/400/240?random=10",
},
{
name: "PORTO Bootstrap Template",
framework: "Bootstrap 5",
price: "$19",
badge: "5.0 ★",
color: "#7952b3",
image: "https://picsum.photos/400/240?random=11",
},
{
name: "Proctu Medical React",
framework: "React 19",
price: "$39",
badge: "New",
color: "#10b981",
image: "https://picsum.photos/400/240?random=12",
},
]
export default function HoverCards() {
return (
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{templates.map((t) => (
<div
key={t.name}
className="group relative overflow-hidden rounded-xl border bg-white shadow-sm cursor-pointer transition-all duration-300 hover:-translate-y-1.5 hover:shadow-xl"
>
{/* Image with zoom */}
<div className="relative overflow-hidden h-40">
<img
src={t.image}
alt={t.name}
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
/>
{/* Overlay on hover */}
<div className="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center gap-2">
<a
href="#"
className="px-3 py-1.5 bg-white text-gray-900 text-xs font-semibold rounded-md hover:bg-gray-100"
>
Preview
</a>
<a
href="https://lettstartdesign.com"
className="px-3 py-1.5 text-white text-xs font-semibold rounded-md flex items-center gap-1"
style={{ background: t.color }}
target="_blank"
rel="noopener"
>
Buy <ExternalLink size={10} />
</a>
</div>
{/* Badge */}
<div className="absolute top-2 left-2">
<span
className="px-2 py-0.5 text-white text-xs font-semibold rounded"
style={{ background: t.color }}
>
{t.badge}
</span>
</div>
</div>
{/* Content */}
<div className="p-3">
<p className="text-xs text-muted-foreground mb-0.5">{t.framework}</p>
<h3 className="font-semibold text-sm">{t.name}</h3>
<div className="flex justify-between items-center mt-2">
<span className="font-bold" style={{ color: t.color }}>{t.price}</span>
<ExternalLink size={14} className="text-gray-400 opacity-0 group-hover:opacity-100 transition-opacity" />
</div>
</div>
</div>
))}
</div>
)
}Frequently Asked Questions
Need a Full React + Next.js Dashboard Template?
Get a complete React + Next.js dashboard with 50+ components — built by the same team behind BootstrapPlanet.
Browse Templates →Use code FIRST30 for 30% off.