Card

A flexible container with four visual variants and an optional interactive mode. Composed from CardHeader, CardBody, and CardFooter for structured layouts.

Preview

Default

Standard bordered card with surface background. The workhorse variant.

Elevated

Drop shadow communicates that this card floats above the page surface.

Variants

Four variants for different elevations and semantic contexts.

default

Border + surface background

elevated

Drop shadow, no extra border style

ghost

No border, subtle filled background

accent

Green-tinted border and background

Interactive

Adding interactive enables hover elevation, accent border on hover, and a subtle press scale. Pair with as="button" or as="a" for correct semantics.

default

Hover me

elevated

Hover me

ghost

Hover me

Implementation

Card, CardHeader, CardBody, and CardFooter are all named exports from the same file. Use them together for structured layouts or use Card alone for simple containers.

Card.tsx
tsx
import { Card, CardHeader, CardBody, CardFooter } from "@/components/ui/Card";
import { Button } from "@/components/ui/Button";

// Default — border + surface background
<Card>
  <CardHeader>
    <h3 className="text-[14px] font-semibold">Project Alpha</h3>
  </CardHeader>
  <CardBody>
    <p className="text-[13px] text-[rgb(var(--text-secondary))]">
      A brief description of the project and its current status.
    </p>
  </CardBody>
  <CardFooter>
    <Button size="sm" variant="secondary">Open</Button>
  </CardFooter>
</Card>

// Elevated — drop shadow
<Card variant="elevated">
  <CardBody>Elevated card with depth shadow.</CardBody>
</Card>

// Ghost — subtle filled background, no border
<Card variant="ghost">
  <CardBody>Ghost card blends into the background.</CardBody>
</Card>

// Accent — green-tinted border and background
<Card variant="accent">
  <CardBody>Accent card for highlighted content.</CardBody>
</Card>

// Interactive — hover + press states
<Card interactive as="button" onClick={() => {}}>
  <CardBody>Click me</CardBody>
</Card>

Props

PropTypeDefaultDescription
variant"default" | "elevated" | "ghost" | "accent""default"Controls border, background, and shadow treatment.
interactivebooleanfalseAdds hover elevation, accent border on hover, and active scale.
as"div" | "button" | "a""div"Render the card as a different HTML element for semantic correctness.

Mobile

Cards on mobile should fill the available width and be large enough to tap comfortably. Avoid dense multi-column grids on narrow screens.

9:41

Browse

Foundation

Design Principles

Core concepts behind Sitka's approach

Component

Button

Interactive control for actions

Foundation

Glass Surface

Layered blur and opacity system

ScenarioGuidance
Grid layoutUse a single column on screens below 640px. Two columns can work above 480px if cards don't contain much text. grid-cols-1 sm:grid-cols-2 is the safe default.
Touch targetInteractive cards should be at least 44px tall. Content-heavy cards usually exceed this naturally, but icon cards and small thumbnails may need extra padding.
Swipe in listsHorizontal card carousels should use scroll-snap-type: x mandatory with scroll-snap-align: start on each card so swipes land cleanly.
Hover statesCards with hover effects (shadow lift, scale) should still look correct without hover on touch. Add an active: pressed state to replace hover feedback.
Image aspect ratioUse aspect-video or aspect-square on card images to prevent layout shift as images load. Avoid auto height with no explicit ratio.

Accessibility

  • Use as="button" or as="a" for interactive cards — never attach onClick to a <div>.
  • Interactive cards have active:scale feedback; avoid additional animations inside that compound the motion.
  • Ensure card content contains a meaningful heading or label for screen readers.
  • Focus ring is inherited from the element — <button> cards receive it automatically.