Github

Card

Displays a card with header, content, and footer.

Login to your account
Enter your email below to login to your account
import { Button } from "@/components/ui/button";
import {
	Card,
	CardAction,
	CardContent,
	CardDescription,
	CardFooter,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

export function CardDemo() {
	return (
		<Card className="w-full max-w-sm">
			<CardHeader>
				<CardTitle>Login to your account</CardTitle>
				<CardDescription>
					Enter your email below to login to your account
				</CardDescription>
				<CardAction>
					<Button variant="ghost">Sign Up</Button>
				</CardAction>
			</CardHeader>
			<CardContent>
				<form>
					<div className="flex flex-col gap-6">
						<div className="grid gap-2">
							<Label htmlFor="email">Email</Label>
							<Input
								variant="secondary"
								id="email"
								type="email"
								placeholder="m@example.com"
								required
							/>
						</div>
						<div className="grid gap-2">
							<div className="flex items-center">
								<Label htmlFor="password">Password</Label>
								<a
									href="#"
									className="ml-auto inline-block text-xs underline-offset-4 hover:underline sm:text-sm"
								>
									Forgot your password?
								</a>
							</div>
							<Input
								variant="secondary"
								id="password"
								type="password"
								required
							/>
						</div>
					</div>
				</form>
			</CardContent>
			<CardFooter className="flex-col gap-2">
				<Button type="submit" className="w-full">
					Login
				</Button>
				<Button variant="outline" className="w-full">
					Login with Google
				</Button>
			</CardFooter>
		</Card>
	);
}

Installation

pnpm dlx shadcn@latest add https://herocn.dev/r/card.json

Usage

import {
  Card,
  CardAction,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
<Card>
  <CardHeader>
    <CardTitle>Card Title</CardTitle>
    <CardDescription>Card Description</CardDescription>
    <CardAction>Card Action</CardAction>
  </CardHeader>
  <CardContent>
    <p>Card Content</p>
  </CardContent>
  <CardFooter>
    <p>Card Footer</p>
  </CardFooter>
</Card>

Composition

Use the following composition to build a Card:

Card
├── CardHeader
│   ├── CardTitle
│   ├── CardDescription
│   └── CardAction
├── CardContent
└── CardFooter

Examples

Variants

Use the variant prop to control the visual prominence of the card.

Transparent
Minimal prominence with transparent background

Use for less important content or nested cards

Default
Standard card appearance (bg-surface)

The default card variant for most use cases

Secondary
Medium prominence (bg-surface-secondary)

Use to draw moderate attention

Tertiary
Higher prominence (bg-surface-tertiary)

Use for primary or featured content

import {
	Card,
	CardContent,
	CardDescription,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";

export function CardVariants() {
	return (
		<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
			<Card variant="transparent">
				<CardHeader>
					<CardTitle>Transparent</CardTitle>
					<CardDescription>
						Minimal prominence with transparent background
					</CardDescription>
				</CardHeader>
				<CardContent>
					<p>Use for less important content or nested cards</p>
				</CardContent>
			</Card>

			<Card variant="default">
				<CardHeader>
					<CardTitle>Default</CardTitle>
					<CardDescription>
						Standard card appearance (bg-surface)
					</CardDescription>
				</CardHeader>
				<CardContent>
					<p>The default card variant for most use cases</p>
				</CardContent>
			</Card>

			<Card variant="secondary">
				<CardHeader>
					<CardTitle>Secondary</CardTitle>
					<CardDescription>
						Medium prominence (bg-surface-secondary)
					</CardDescription>
				</CardHeader>
				<CardContent>
					<p>Use to draw moderate attention</p>
				</CardContent>
			</Card>

			<Card variant="tertiary">
				<CardHeader>
					<CardTitle>Tertiary</CardTitle>
					<CardDescription>
						Higher prominence (bg-surface-tertiary)
					</CardDescription>
				</CardHeader>
				<CardContent>
					<p>Use for primary or featured content</p>
				</CardContent>
			</Card>
		</div>
	);
}

Size

Use the size="sm" prop to set the size of the card to small. The small size variant uses smaller spacing.

Scheduled reports
Weekly snapshots. No more manual exports.
  • Choose a schedule (daily, or weekly).
  • Send to channels or specific teammates.
  • Include charts, tables, and key metrics.
import { ChevronRightIcon } from "lucide-react";

import { Button } from "@/components/ui/button";
import {
	Card,
	CardContent,
	CardDescription,
	CardFooter,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";

export function CardSmall() {
	const featureName = "Scheduled reports";

	return (
		<Card size="sm" className="mx-auto w-full max-w-xs">
			<CardHeader>
				<CardTitle>{featureName}</CardTitle>
				<CardDescription>
					Weekly snapshots. No more manual exports.
				</CardDescription>
			</CardHeader>
			<CardContent>
				<ul className="grid gap-2 py-2 text-sm">
					<li className="flex gap-2">
						<ChevronRightIcon className="mt-0.5 size-4 shrink-0 text-muted-foreground" />
						<span>Choose a schedule (daily, or weekly).</span>
					</li>
					<li className="flex gap-2">
						<ChevronRightIcon className="mt-0.5 size-4 shrink-0 text-muted-foreground" />
						<span>Send to channels or specific teammates.</span>
					</li>
					<li className="flex gap-2">
						<ChevronRightIcon className="mt-0.5 size-4 shrink-0 text-muted-foreground" />
						<span>Include charts, tables, and key metrics.</span>
					</li>
				</ul>
			</CardContent>
			<CardFooter className="flex-col gap-2">
				<Button size="sm" className="w-full">
					Set up scheduled reports
				</Button>
				<Button variant="outline" size="sm" className="w-full">
					See what&apos;s new
				</Button>
			</CardFooter>
		</Card>
	);
}

Image

Add an image before the card header to create a card with an image.

Event cover
Featured
Design systems meetup
A practical talk on component APIs, accessibility, and shipping faster.
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
	Card,
	CardAction,
	CardDescription,
	CardFooter,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";

export function CardImage() {
	return (
		<Card className="relative w-full max-w-sm">
			<img
				src="https://avatar.vercel.sh/shadcn1"
				alt="Event cover"
				className="relative z-20 aspect-video w-full object-cover"
			/>
			<CardHeader>
				<CardAction>
					<Badge>Featured</Badge>
				</CardAction>
				<CardTitle>Design systems meetup</CardTitle>
				<CardDescription>
					A practical talk on component APIs, accessibility, and shipping
					faster.
				</CardDescription>
			</CardHeader>
			<CardFooter>
				<Button className="w-full">View Event</Button>
			</CardFooter>
		</Card>
	);
}

RTL

تسجيل الدخول إلى حسابك
أدخل بريدك الإلكتروني أدناه لتسجيل الدخول إلى حسابك
"use client";

import {
	type Translations,
	useTranslation,
} from "@/components/language-selector";
import { Button } from "@/components/ui/button";
import {
	Card,
	CardAction,
	CardContent,
	CardDescription,
	CardFooter,
	CardHeader,
	CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

const translations: Translations = {
	en: {
		dir: "ltr",
		values: {
			title: "Login to your account",
			description: "Enter your email below to login to your account",
			signUp: "Sign Up",
			email: "Email",
			emailPlaceholder: "m@example.com",
			password: "Password",
			forgotPassword: "Forgot your password?",
			login: "Login",
			loginWithGoogle: "Login with Google",
		},
	},
	ar: {
		dir: "rtl",
		values: {
			title: "تسجيل الدخول إلى حسابك",
			description: "أدخل بريدك الإلكتروني أدناه لتسجيل الدخول إلى حسابك",
			signUp: "إنشاء حساب",
			email: "البريد الإلكتروني",
			emailPlaceholder: "m@example.com",
			password: "كلمة المرور",
			forgotPassword: "نسيت كلمة المرور؟",
			login: "تسجيل الدخول",
			loginWithGoogle: "تسجيل الدخول باستخدام Google",
		},
	},
	he: {
		dir: "rtl",
		values: {
			title: "התחבר לחשבון שלך",
			description: "הזן את האימייל שלך למטה כדי להתחבר לחשבון שלך",
			signUp: "הירשם",
			email: "אימייל",
			emailPlaceholder: "m@example.com",
			password: "סיסמה",
			forgotPassword: "שכחת את הסיסמה?",
			login: "התחבר",
			loginWithGoogle: "התחבר עם Google",
		},
	},
};

export function CardRtl() {
	const { dir, language, t } = useTranslation(translations, "ar");

	return (
		<Card className="w-full max-w-sm" lang={language} dir={dir}>
			<CardHeader>
				<CardTitle>{t.title}</CardTitle>
				<CardDescription>{t.description}</CardDescription>
				<CardAction>
					<Button variant="ghost">{t.signUp}</Button>
				</CardAction>
			</CardHeader>
			<CardContent>
				<form>
					<div className="flex flex-col gap-6">
						<div className="grid gap-2">
							<Label htmlFor="email-rtl">{t.email}</Label>
							<Input
								variant="secondary"
								id="email-rtl"
								type="email"
								placeholder={t.emailPlaceholder}
								required
							/>
						</div>
						<div className="grid gap-2">
							<div className="flex items-center">
								<Label htmlFor="password-rtl">{t.password}</Label>
								<a
									href="#"
									className="ms-auto inline-block text-xs underline-offset-4 hover:underline md:text-sm"
								>
									{t.forgotPassword}
								</a>
							</div>
							<Input
								variant="secondary"
								id="password-rtl"
								type="password"
								required
							/>
						</div>
					</div>
				</form>
			</CardContent>
			<CardFooter className="flex-col gap-2">
				<Button type="submit" className="w-full">
					{t.login}
				</Button>
				<Button variant="outline" className="w-full">
					{t.loginWithGoogle}
				</Button>
			</CardFooter>
		</Card>
	);
}

API Reference

Card

PropTypeDefault
size"default" | "sm"
"default"
classNamestring

CardHeader

The CardHeader component is used for a title, description, and optional action.

PropTypeDefault
classNamestring

CardTitle

The CardTitle component is used for the card title.

PropTypeDefault
classNamestring

CardDescription

The CardDescription component is used for helper text under the title.

PropTypeDefault
classNamestring

CardAction

The CardAction component places content in the top-right of the header (for example, a button or a badge).

PropTypeDefault
classNamestring

CardContent

The CardContent component is used for the main card body.

PropTypeDefault
classNamestring

CardFooter

The CardFooter component is used for actions and secondary content at the bottom of the card.

PropTypeDefault
classNamestring