Installation
pnpm dlx shadcn@latest add https://rdf.dev.360online.com/r/card.jsonInstalls to @/components/ui/card.
Manual installation
Copy the source into your project:
import type * as React from 'react'
import { cn } from '@/lib/utils'
function Card({ className, size = 'default', ...props }: React.ComponentProps<'div'> & { size?: 'default' | 'sm' }) {
return (
// min-h-min: overflow-hidden would let a flex column shrink the card below its content and clip it; pass
// `min-h-0` to let a card shrink and scroll inside instead
<div
data-slot="card"
data-size={size}
className={cn(
'group/card flex min-h-min flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground border border-border [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl',
className,
)}
{...props}
/>
)
}
function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-header"
className={cn(
'group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] border-b pb-(--card-spacing)',
className,
)}
{...props}
/>
)
}
function CardTitle({
className,
as: Heading = 'h3',
...props
}: React.ComponentProps<'h3'> & {
/** Heading level to render, so the card fits the page's heading outline */
as?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
}) {
return (
<Heading
data-slot="card-title"
className={cn('font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm', className)}
{...props}
/>
)
}
function CardDescription({ className, ...props }: React.ComponentProps<'p'>) {
return <p data-slot="card-description" className={cn('text-sm text-muted-foreground', className)} {...props} />
}
function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-action"
className={cn('col-start-2 row-span-2 row-start-1 self-start justify-self-end', className)}
{...props}
/>
)
}
function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
return <div data-slot="card-content" className={cn('px-(--card-spacing)', className)} {...props} />
}
function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-footer"
className={cn('flex items-center rounded-b-xl border-t p-(--card-spacing)', className)}
{...props}
/>
)
}
export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent }A versatile card component that serves as a container for content, with support for headers, actions, footers, and various content layouts. Built with Tailwind CSS, it provides a consistent and customizable way to display grouped content.
Features
- Composable parts:
Card,CardHeader,CardTitle,CardDescription,CardAction,CardContent,CardFooter CardActionslot placed in the top-right corner of the header- Two sizes via
size:defaultandsm(tighter spacing and smaller title) - Header with a divider below it (remove it with
className="border-b-0 pb-0") - Footer with a top border
- Edge-to-edge images when an
imgis the first or last child data-slotattributes on every part for styling hooks- Custom styling support via
className
Usage
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
export function CaseCard() {
return (
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle>Extension of detached house</CardTitle>
<CardDescription>Case 2026-04812 · Storgatan 14</CardDescription>
<CardAction>
<Button variant="outline" size="sm">
Edit
</Button>
</CardAction>
</CardHeader>
<CardContent>
<p>Received 12 February 2026. Decision due 12 March 2026.</p>
</CardContent>
<CardFooter>
<Button size="sm">Open case</Button>
</CardFooter>
</Card>
)
}
// Compact card
export function StatCard() {
return (
<Card size="sm">
<CardHeader>
<CardDescription>Open cases</CardDescription>
<CardTitle>128</CardTitle>
</CardHeader>
<CardContent>+12 this week</CardContent>
</Card>
)
}Examples
Default
A short e-service form for a parking permit, with header, content and footer.
With Action
Place a button or menu trigger in CardAction to align it with the header, here next to a list of notification
settings.
Small
size="sm" reduces the card spacing and title size, which suits a row of key figures on a dashboard. The header
divider is removed with className="border-b-0 pb-0".
With Image
A municipal facility card with an image area on top. An img as the first child sits edge to edge automatically; for
any other element, remove the top padding with pt-0.
Case Summary
A summary of a case in case management: key facts, the case officer and a link to the full case.
Loading State
Compose Skeleton placeholders that mirror the final layout while content loads.
Props
Card-size?: 'default' | 'sm'(default'default'), plus alldivattributesCardTitle- renders a heading;as?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6'(default'h3'), plus all heading attributesCardDescription- renders ap, plus allpattributesCardHeader,CardAction,CardContent,CardFooter- alldivattributes
Pick the CardTitle level that fits the page's heading outline, e.g. <CardTitle as="h2">Title</CardTitle>.
Accessibility
CardTitlerenders a real heading (h3by default); setasto match the page's heading levelsCardDescriptionrenders a paragraph- Ensure interactive elements in
CardActionhave accessible labels - Ensure proper color contrast for custom backgrounds
Best Practices
-
Content Structure:
- Use clear hierarchy
- Keep content concise
- Group related information
-
Actions:
- Use
CardActionfor a single secondary action in the header - Put primary actions in
CardFooter
- Use
-
Responsive Design:
- Set appropriate widths
- Handle image scaling
- Use
size="sm"in dense layouts
-
Loading:
- Use
Skeletonto mirror the final layout
- Use
Related Components
- Skeleton
- Button