Skip to content

Card

Terminal window
npx bambiui add card

The CLI copies the Card source into your project. Installed files are self-contained.

Import the token file once from your global stylesheet:

@import "./styles/bambi.css";

Then import the component:

import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './components/ui/card';

Use props-driven Card props for common layouts. Use the compound API when you need custom structure or full control. Both styles render the same bambi-card-* structure.

<Card
title="Account settings"
description="Manage your account preferences."
footer={<Button>Save</Button>}
>
Your content goes here.
</Card>

Use compound pieces for advanced layouts, custom headings, or non-standard section order.

<Card>
<CardHeader>
<CardTitle>Account settings</CardTitle>
<CardDescription>Manage your account preferences.</CardDescription>
</CardHeader>
<CardContent>
<p>Your content goes here.</p>
</CardContent>
<CardFooter>
<Button>Save</Button>
</CardFooter>
</Card>
<Card variant="default">Default</Card>
<Card variant="outline">Outline</Card>
<Card variant="ghost">Ghost</Card>
<Card variant="elevated">Elevated</Card>
<Card size="sm">Small padding</Card>
<Card size="md">Medium padding (default)</Card>
<Card size="lg">Large padding</Card>

Use interactive (or CardLink in React) for clickable cards. Always prefer real link or button semantics.

{/* Renders as <a> with full keyboard and focus support */}
<CardLink href="/projects/1">
<CardHeader>
<CardTitle>Project Alpha</CardTitle>
<CardDescription>View project details</CardDescription>
</CardHeader>
</CardLink>
{/* Renders as <div data-interactive> */}
<Card interactive onClick={() => navigate('/projects/1')}>
<CardContent>Clickable card</CardContent>
</Card>

The following CSS classes are available for structuring card content in any framework:

ClassElement
bambi-cardRoot card container
bambi-card-headerHeader section
bambi-card-titleTitle text
bambi-card-descriptionDescription text
bambi-card-contentMain content area
bambi-card-footerFooter action area
PropTypeDefaultDescription
variant'default' | 'outline' | 'ghost' | 'elevated''default'Visual card style
size'sm' | 'md' | 'lg''md'Section padding density
interactivebooleanfalseAdds interactive card affordances
titleframework text/node propConvenience title rendered as bambi-card-title
descriptionframework text/node propConvenience description rendered as bambi-card-description
headerReact node / Svelte snippet / Vue or Astro slotCustom convenience header content
footerReact node / Svelte snippet / Vue or Astro slotFooter content rendered as bambi-card-footer
actionsReact node / Svelte snippet / Vue or Astro slotAlternate footer/action content
  • Use CardLink or a real anchor/button for navigable or actionable cards.
  • Props-driven sections render the same semantic classes as the compound API.
  • Choose the heading level in compound React usage with CardTitle as="h2" when the page hierarchy requires it.
PropTypeDefaultDescription
variant'default' | 'outline' | 'ghost' | 'elevated''default'Visual style
size'sm' | 'md' | 'lg''md'Padding density
interactivebooleanfalseAdds hover/focus styles; use real <a> for navigation

React also exports CardLink (renders <a>), CardHeader, CardTitle, CardDescription, CardContent, and CardFooter as helper components. All forward HTML attributes.

  • Plain layout cards use no ARIA roles — they are correctly treated as generic containers.
  • When the card is interactive, use CardLink (React) or an <a> element for navigation, or a <button> for actions. This ensures keyboard access and correct screen-reader announcements.
  • CardTitle renders as <h3> by default in React; pass as="h2" etc. to match document outline. In Svelte/Vue/Astro use the appropriate heading element directly.
  • Visible focus ring is applied via :focus-visible on interactive cards.