Skip to content

Card

Simple bordered card primitives with floating border labels and semantic HTML support.

Preview

Installation

$pnpm exec dgadd add ui/card
[Installs to]src/components/ui/card[Item]ui/card

dgadd is not public on npm yet. Until the first release, pack @diffgazer/add from the repository and install that tarball into this app, which is what puts dgadd on pnpm exec.

UI components require Tailwind CSS v4. Local copy mode imports src/styles/styles.css; package mode uses @diffgazer/ui CSS once packages are available.

Usage

tsx
import { Button } from "@/components/ui/button";import { Card, CardContent, CardFooter, CardLabel } from "@/components/ui/card";export default function CardDefault() {  return (    <Card size="md">      <CardLabel variant="border">Repository</CardLabel>      <CardContent className="pt-6">        <div className="space-y-4 text-sm">          <p className="text-muted-foreground">Simple bordered card with floating border label.</p>          <div className="flex justify-between py-1 border-b border-border">            <span className="text-muted-foreground">Branch</span>            <span className="font-mono">main</span>          </div>          <div className="flex justify-between py-1 border-b border-border">            <span className="text-muted-foreground">Commit</span>            <span className="font-mono">a1b2c3d</span>          </div>          <div className="flex justify-between py-1">            <span className="text-muted-foreground">Status</span>            <span className="font-bold text-success">PASS</span>          </div>        </div>      </CardContent>      <CardFooter>        <Button variant="ghost">Cancel</Button>        <Button variant="primary">Save</Button>      </CardFooter>    </Card>  );}

Examples

Surfaces

Preview

Interactive

Preview

Sizes

Preview

Header Action

Preview

Article (accessible)

Preview

API Reference

Card

NameTypeDefaultDescription
as"div" | "article" | "section" | "aside" | "a" | "button""div"Rendered HTML element. Use article/section/aside when the card is a self-contained content region, or a/button to make an interactive card keyboard-focusable.
surface"flat" | "stacked" | "inset" | "dotted" | "glow""flat"Surface treatment. Flat is a clean border, stacked adds a hard offset plate, inset steps the background down, dotted uses a dashed wireframe border, and glow doubles the outer edge.
interactivebooleanfalseEnables hover and focus-visible states with surface-specific treatments. Pair with a focusable host (as='a' or as='button') so keyboard users can reach the card.
size"default" | "sm" | "md" | "lg""default"Max-width constraint. Default is full width.
childrenReactNodeCard subparts (Header, Label, Content, Footer, etc.).

Card.Label

NameTypeDefaultDescription
variant"border" | "gap""border"Visual treatment of the floating label. Border boxes the label; gap omits the box.
childrenReactNodeLabel content.

Card.Title

NameTypeDefaultDescription
as"h2" | "h3" | "h4" | "h5""h3"Heading level. Match your document outline.
childrenReactNodeTitle text.

Card.Description

NameTypeDefaultDescription
childrenReactNodeSupporting description text.

Card.Header

NameTypeDefaultDescription
childrenReactNodeHeader content. When a Card.Action child is present, the header switches to a two-column grid.

Card.Action

NameTypeDefaultDescription
childrenReactNodeAction element (button or badge) anchored to the top-right of Card.Header.

Card.Content

NameTypeDefaultDescription
childrenReactNodeBody content.
NameTypeDefaultDescription
childrenReactNodeFooter actions or meta, right-aligned by default.

Accessibility

Notes

Surfaces

Card supports five surface treatments: flat (default clean border), stacked (paper-stack depth from a hard offset plate), inset (recessed surface step), dotted (dashed wireframe border), and glow (hard doubled outer edge). Depth comes from borders and background steps — cards never cast a soft shadow. Use surface='flat' for everyday cards, surface='stacked' for elevated emphasis, surface='inset' for recessed areas, surface='dotted' for drafts or placeholders, and surface='glow' for highlighted content.

Interactive

Add the interactive prop to enable hover and focus-visible states. Each surface has a unique hover treatment: flat brightens the border, stacked grows the offset plate, inset deepens the recessed fill, dotted brightens the dashed border, and glow strengthens the outer edge. The interactive prop only styles the surface — it does not make a div focusable. Render an interactive card on a focusable host (as='a' with href, or as='button' with onClick) or wrap its content in a link/button so keyboard users can reach it and the focus-visible treatment is reachable. See the Interactive example.

Floating Border Labels

Use CardLabel variant='border' for a boxed border label, or variant='gap' for a border cutout label with no border around the text. When using CardLabel, add pt-6 (or similar) to sibling CardContent to clear the floating label.

Padding rhythm

CardHeader, CardContent, and CardFooter all use px-6, so header text, body text, and footer actions share one vertical edge. Only the block padding differs per region (header py-3, content p-6, footer py-4). Override className if a product layout needs a different rhythm — but override all three regions together, never one.

Size

Card supports size='sm' | 'md' | 'lg' for max-width constraints. Default is full width.

Heading Level

CardTitle renders an h3 by default. Use the as prop to change the heading level (h2, h3, h4, h5).

Header Actions

Use CardAction inside CardHeader to place an action (button, badge) in the top-right corner. The header switches to a two-column grid layout automatically when CardAction is present.

Semantic HTML

Card renders a div by default. Use as='article' for self-contained content, as='section' for grouped content, or as='aside' for tangential content.

Accessible Article Cards

When using as='article', connect the card to its heading with aria-labelledby so screen readers announce card boundaries. Give CardTitle an id and pass the same id to Card's aria-labelledby. See the Article example.

Source

Install via CLI: pnpm exec dgadd add ui/card.

Highlighted source loads after this disclosure opens. Browse the source repository.