Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by shadcn
Edit on GitHub

Card

Displays a card with header, content, and footer.

Powered by

Installation

bash
npx shadcn@latest add @redpanda/card
bash
pnpm dlx shadcn@latest add @redpanda/card
bash
yarn dlx shadcn@latest add @redpanda/card
bash
bunx shadcn@latest add @redpanda/card
bash
nubx shadcn@latest add @redpanda/card
bash
aube dlx shadcn@latest add @redpanda/card

Usage

The Card component provides a flexible container for grouping related content and actions. It supports multiple sizes, variants, and includes specialized form helpers for common use cases.

tsx
import {  Card,  CardContent,  CardDescription,  CardFooter,  CardHeader,  CardTitle,  CardForm,  CardField,} from '@/components/redpanda-ui/card';

When to use

Use this decision tree to determine when to use the Card component:

Use Card when:

  • Grouping related information and actions
  • Creating forms with consistent layout
  • Displaying structured content with header/footer
  • Building dashboard widgets or panels
  • Containing interactive elements that belong together

Don’t use Card for:

  • Single pieces of information (use Typography)
  • Navigation elements (use Navigation components)
  • Modal overlays (use Dialog/Sheet)
  • Simple dividers (use Separator)

Anatomy

The Card component is built with a flexible system of sub-components that work together:

plaintext
Card Component Structure:┌─────────────────────────────────────────────────────┐│ <Card> (Container with padding, border, background) ││ ┌─────────────────────────────────────────────────┐ ││ │ <CardHeader> (Optional)                         │ ││ │ ┌─────────────────┐ ┌─────────────────────────┐ │ ││ │ │ Left Content    │ │ <CardAction> (Optional) │ │ ││ │ │ ┌─────────────┐ │ │ - Buttons/Icons         │ │ ││ │ │ │<CardTitle>  │ │ │ - Menu triggers         │ │ ││ │ │ └─────────────┘ │ │                         │ │ ││ │ │ ┌─────────────┐ │ │                         │ │ ││ │ │ │<CardDesc>   │ │ │                         │ │ ││ │ │ └─────────────┘ │ │                         │ │ ││ │ └─────────────────┘ └─────────────────────────┘ │ ││ └─────────────────────────────────────────────────┘ ││ ┌─────────────────────────────────────────────────┐ ││ │ <CardContent> (Main content area)               │ ││ │                                                 │ ││ │ For forms:                                      │ ││ │ ┌─────────────────────────────────────────────┐ │ ││ │ │ <CardForm> (Grid layout)                    │ │ ││ │ │ ┌─────────────┐ ┌─────────────────────────┐ │ │ ││ │ │ │ <CardField> │ │ <CardField>             │ │ │ ││ │ │ │ [Label]     │ │ [Label]                 │ │ │ ││ │ │ │ [Input]     │ │ [Select/Textarea/etc]   │ │ │ ││ │ │ └─────────────┘ └─────────────────────────┘ │ │ ││ │ └─────────────────────────────────────────────┘ │ ││ └─────────────────────────────────────────────────┘ ││ ┌─────────────────────────────────────────────────┐ ││ │ <CardFooter> (Actions/Navigation)               │ ││ │ [Button] [Button] ... [Button]                  │ ││ │ (justification: start|center|end|between)       │ ││ └─────────────────────────────────────────────────┘ │└─────────────────────────────────────────────────────┘
Size System:• sm: Max-width 384px, compact padding (px-6 py-4)• md: Max-width 448px, standard padding (px-8 py-6)• lg: Max-width 512px, generous padding (px-10 py-8)• xl: Max-width 576px, spacious padding (px-12 py-10)• full: Full width, standard padding (px-8 py-6)
Variant System:• default: Standard card with border and shadow• elevated: Enhanced shadow for prominence• outlined: Thicker border, less shadow• ghost: Transparent background, no border/shadow
Form Helpers:• CardForm: Automatic grid layout with consistent spacing• CardField: Vertical label/input layout with proper spacing

Basic Card

tsx
<Card size="md">  <CardHeader>    <CardTitle>Card Title</CardTitle>    <CardDescription>Card Description</CardDescription>  </CardHeader>  <CardContent>    <p>Card Content</p>  </CardContent>  <CardFooter>    <p>Card Footer</p>  </CardFooter></Card>

Form Card (Simplified Layout)

tsx
<Card size="sm">  <CardHeader>    <CardTitle>Contact Form</CardTitle>    <CardDescription>Get in touch with us</CardDescription>  </CardHeader>  <CardContent>    <CardForm>      <CardField>        <Label htmlFor="name">Name</Label>        <Input id="name" placeholder="Your name" />      </CardField>      <CardField>        <Label htmlFor="email">Email</Label>        <Input id="email" type="email" placeholder="your@email.com" />      </CardField>    </CardForm>  </CardContent>  <CardFooter>    <Button>Submit</Button>  </CardFooter></Card>

Variants

Card Sizes

The Card component supports multiple sizes to fit different use cases:

tsx
<Card size="sm">Small card (max-w-sm, px-6 py-4)</Card><Card size="md">Medium card (max-w-md, px-8 py-6)</Card><Card size="lg">Large card (max-w-lg, px-10 py-8)</Card><Card size="xl">Extra large card (max-w-xl, px-12 py-10)</Card><Card size="full">Full width card (w-full, px-8 py-6)</Card>

Edge-to-edge composition

Use padding="none" for media and rows that touch the card edge. This keeps the chosen size’s width and gap while removing its outer padding.

CardHeader, CardContent, and CardFooter accept horizontal padding="sm" | "md" | "lg" (12, 24, or 32 pixels). A padded header or footer directly inside an edge-to-edge card also supplies its matching top or bottom inset. Use these props rather than padding overrides on the component.

tsx
<Card padding="none" size="sm">  <img alt="Cluster architecture" src="/cluster-architecture.webp" />  <CardHeader padding="md">    <CardTitle>Cluster architecture</CardTitle>  </CardHeader>  <CardContent padding="md">Provision topics and consumer groups.</CardContent>  <CardFooter padding="md">    <Button type="submit">Create cluster</Button>  </CardFooter></Card>

Card Variants

tsx
<Card variant="standard">Standard styling</Card><Card variant="elevated">Enhanced shadow</Card><Card variant="outlined">Thicker border</Card><Card variant="ghost">No background or border</Card>
tsx
<CardFooter justify="between">Buttons on sides</CardFooter><CardFooter justify="end">Buttons on right</CardFooter><CardFooter direction="column">Stacked buttons</CardFooter>

Separated sections

Use separator on a CardHeader or CardFooter to add the section border and its content inset together. Small cards use a 16-pixel inset; other sizes use 24 pixels, including the default medium size when size is omitted. Separators are opt-in and do not change unseparated sections.

tsx
<Card size="sm">  <CardHeader separator>    <CardTitle>Appointment</CardTitle>  </CardHeader>  <CardContent>Choose a date and time.</CardContent>  <CardFooter direction="column" gap="md" separator>    <p>Review your appointment details.</p>    <Button type="submit">Book appointment</Button>  </CardFooter></Card>

Prefer the card’s size and section recipes over adding padding or border utilities to its parts. Use gap="sm" | "md" | "lg" for footer spacing. Existing border-t and border-b class hooks retain their previous spacing for compatibility; new compositions should use separator instead.

Form Helpers

The CardForm and CardField components eliminate the need for manual layout classes:

  • CardForm: Provides consistent grid layout and spacing for form elements
  • CardField: Handles label and input spacing automatically
tsx
// Before (manual layout)<div className="grid w-full items-center gap-4">  <div className="flex flex-col space-y-1.5">    <Label>Name</Label>    <Input />  </div></div>
// After (automatic layout)<CardForm>  <CardField>    <Label>Name</Label>    <Input />  </CardField></CardForm>

Examples

Default

Login example

With image

With header action

With table

Outlined

Elevated

Interactive

ListCard

When displaying items in a list or grid of cards (like a model catalog, user list, or resource browser), use ListCard instead of the base Card:

tsx
import {  ListCard,  ListCardHeader,  ListCardMeta,  ListCardBody,  ListCardDescription,  ListCardFooter,} from '@/components/redpanda-ui/list-card';
<ListCard>  <ListCardHeader end={<Badge>Active</Badge>}>Claude 3.5 Sonnet</ListCardHeader>  <ListCardMeta>Anthropic • claude-3-5-sonnet</ListCardMeta>  <ListCardBody>    <ListCardDescription>Most intelligent model with state-of-the-art reasoning.</ListCardDescription>  </ListCardBody>  <ListCardFooter end={<Button size="sm">Configure</Button>} /></ListCard>;

Use ListCard when:

  • Displaying a collection of similar items in a grid
  • Each item has consistent structure (title, description, actions)
  • You want automatic text truncation and slot-based layout
  • Pairing with ListView for list/grid toggle

Use Card directly when:

  • Building forms or settings panels
  • Creating one-off layouts with unique structure
  • Need full flexibility in content arrangement
  • Content doesn’t fit the header/body/footer pattern

ListView

For horizontal list rows instead of cards, see ListView. Both components share the same data model, making it easy to offer users a choice between list and grid views.

Credits

  • We take our inspiration from Shadcn UI for the card component and style.

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →

Last updated on

Was this page helpful?