Components
Displays a card with header, content, and footer.
Playground
Card from CardHeader —which groups CardTitle, CardDescription and an optional CardAction pinned to the top end—, CardContent and CardFooter. Every part renders a plain div, so all sections are optional and accept any div props.Card Content
Card Footer
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@workspace/ui/components/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>CardAction link, form fields in CardContent, and stacked actions in a CardFooter with flex-col.<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="link">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 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="ms-auto inline-block text-sm underline-offset-4 hover:underline"
>
Forgot your password?
</a>
</div>
<Input 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>size="sm" for a compact card — it drops --card-spacing from 24px to 16px and the title from text-lg to text-sm.The card component supports a size prop that can be set to "sm" for a more compact appearance.
<Card size="sm" className="w-full max-w-sm">
<CardHeader>
<CardTitle>Small Card</CardTitle>
<CardDescription>
This card uses the small size variant.
</CardDescription>
</CardHeader>
<CardContent>
<p>
The card component supports a size prop that can be set to
"sm" for a more compact appearance.
</p>
</CardContent>
<CardFooter>
<Button variant="outline" size="sm" className="w-full">
Action
</Button>
</CardFooter>
</Card>size prop, the --card-spacing CSS variable controls the gap between sections and the inset of every part — set it with an arbitrary property like [--card-spacing:--spacing(8)]. Adding border-b to the header or border-t to the footer also restores their inner padding automatically.Every section inset and the gap between sections track the same variable, so the whole card scales together.
<Card className="w-full max-w-sm [--card-spacing:--spacing(8)]">
<CardHeader className="border-b">
<CardTitle>Roomy card</CardTitle>
<CardDescription>
This card overrides --card-spacing to 32px.
</CardDescription>
</CardHeader>
<CardContent>
<p>
Every section inset and the gap between sections track the same
variable, so the whole card scales together.
</p>
</CardContent>
</Card>-mx-(--card-spacing) to make content run edge to edge while staying aligned with the card inset. When the edge-to-edge block sits above a footer, add -mb-(--card-spacing) to CardContent to remove the section gap, and border-t to the CardFooter so it restores its own padding above the actions.These terms govern your use of the workspace, including access to shared documents, project files, and collaboration tools.
You are responsible for the content you upload and for ensuring that your team has the appropriate permissions to view or edit it.
We may update features or limits as the service evolves. When those changes materially affect your workflow, we will notify your workspace administrators.
By continuing, you agree to keep your account credentials secure and to follow the acceptable use policies of your organization.
<Card className="w-full max-w-sm">
<CardHeader>
<CardTitle>Terms of Service</CardTitle>
<CardDescription>
Review the terms before accepting the agreement.
</CardDescription>
</CardHeader>
<CardContent className="-mb-(--card-spacing)">
<div className="-mx-(--card-spacing) max-h-48 space-y-4 overflow-y-scroll border-t bg-muted/50 px-(--card-spacing) py-4 text-sm leading-relaxed">
<p>...</p>
</div>
</CardContent>
<CardFooter className="justify-end gap-2 border-t">
<Button variant="outline">Decline</Button>
<Button>Accept</Button>
</CardFooter>
</Card>img as the first child of the card to build a cover — the card removes its own top padding and rounds the image corners automatically via has-[>img:first-child]:pt-0. The same applies to a trailing image and the bottom corners.<Card className="w-full max-w-sm">
<img
src="/images/event-cover.jpg"
alt="Event cover"
className="aspect-video w-full object-cover"
/>
<CardHeader>
<CardAction>
<Badge variant="secondary">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>dir="rtl" on the card or inherit it from a Direction provider — the CardAction column and logical spacing classes like ms-auto flip automatically.<Card dir="rtl" className="w-full max-w-sm">
<CardHeader>
<CardTitle>تسجيل الدخول إلى حسابك</CardTitle>
<CardDescription>
أدخل بريدك الإلكتروني أدناه لتسجيل الدخول إلى حسابك
</CardDescription>
<CardAction>
<Button variant="link">إنشاء حساب</Button>
</CardAction>
</CardHeader>
<CardContent>
<div className="grid gap-2">
<Label htmlFor="email">البريد الإلكتروني</Label>
<Input id="email" type="email" placeholder="m@example.com" required />
</div>
</CardContent>
<CardFooter className="flex-col gap-2">
<Button type="submit" className="w-full">
تسجيل الدخول
</Button>
</CardFooter>
</Card>div and accepts all div props — only Card adds a prop of its own. Spacing is driven by the --card-spacing variable, which the size prop presets and any className can override.| Prop | Type | Default |
|---|---|---|
| Card size | "default" | "sm" | "default" |
| className (all parts) | string | — |
| --card-spacing | CSS length | --spacing(6) / --spacing(4) on sm |
Tokens used
10 design tokens consumed by the Card component.
--card
Card
--card-foreground
Card Foreground
--muted-foreground
Muted Foreground
--foreground
Foreground
--font-heading
GT Alpina Condensed
--font-weight-medium
Font weight Medium (500)
--text-lg
Text Large (18px)
--text-sm
Text Small (14px)
--radius-xl
Radius 1.4× (14px)
--spacing
Spacing unit (4px)