Cards

Cards are flexible containers that group related content and actions. They provide a clean, elevated surface for displaying everything from simple text to complex interactive layouts.


Installation

Copy the card CSS from styles/docs.css or include the Standard stylesheet:

<link rel="stylesheet" href="standard.min.css">

Then use card classes in your HTML:

<div class="Card">
    <div class="Card-body">
        <h3 class="Card-title">Card Title</h3>
        <p class="Card-text">Card content goes here.</p>
    </div>
</div>

Usage

The base .Card class provides core styling with elevation and border radius. Add sections like .Card-header, .Card-body, and .Card-footer to structure content.

Simple Card

Cards group related content and actions together.


Examples

Basic Card

A minimal card with title and text content.

Project Update

The new dashboard feature is ready for review. All tests passing.

Use header and footer sections for titles, metadata, and actions.

Weekly Report

Feb 3, 2026

Revenue increased 12% this week. Customer satisfaction scores remain high at 4.8/5.

Card with Image

Add images to cards using .Card-image at the top.

Mountain Retreat

Escape to the peaks for a weekend of hiking and relaxation.

Card with Image Overlay

Overlay text on images for hero-style cards.

Featured

Sunset Photography Workshop

Learn to capture golden hour magic

Horizontal Card

Side-by-side layout for media and content.

Article

Design Systems at Scale

How leading teams maintain consistency across products.

8 min read

Interactive Card

Clickable cards with hover effects.

Profile Card

Display user information and quick actions.

Alex Chen

Senior Product Designer

Creating delightful experiences at Acme Corp. Previously at Figma.

Stats Card

Highlight key metrics and numbers.

2,847 Total Users +12.5%
$48.2k Revenue +8.2%
94.2% Uptime -0.3%

Pricing Card

Display pricing tiers and features.

Popular

Pro

$29 /month
  • Unlimited projects
  • 50GB storage
  • Priority support
  • Advanced analytics
  • Custom domain

Product Card

E-commerce style product display.

Electronics

Wireless Headphones

(128)
$79.99 $99.99

Notification Card

Alert or notification style cards.

New Feature Available

Dark mode is now available. Update your preferences in settings.

Payment Successful

Your subscription has been renewed for another year.

List Card

Cards containing list items.

Recent Activity

  • Document uploaded report-q4.pdf • 2 min ago
  • New team member Sarah joined Design • 1 hour ago
  • Project starred Standard Design System • 3 hours ago

Variants

Elevated

Default cards have subtle elevation with shadow.

Elevated Card

Default shadow provides depth.

Outlined

Border-only variant without shadow.

Outlined Card

Clean border, no shadow.

Flat

No border or shadow — blends with background.

Flat Card

Minimal visual weight.

Filled

Filled background without shadow.

Filled Card

Solid background color.


Padding Sizes

Compact

Less padding

Default

Standard padding

Spacious

More padding


Card Grid

Responsive grid layout for multiple cards.

Card One

Description text for the first card.

Card Two

Description text for the second card.

Card Three

Description text for the third card.


Common Patterns

Dashboard Cards

1,284 Active Users +5.2%
$32.1k Monthly Revenue +11%
98.7% Uptime -0.1%

Card in a Settings Page

Notifications

Email notifications
Push notifications

Trip Photos

12 photos · June 2025

Card as Empty State

No projects yet

Create your first project to get started.


Customization

Override card styles using CSS custom properties:

/* Custom card background */
.Card--custom {
  --card-bg: oklch(95% 0.02 250);
  --card-border: oklch(85% 0.05 250);
  background-color: var(--card-bg);
  border-color: var(--card-border);
}

/* Custom shadow depth */
.Card--deep {
  box-shadow: 
    0 4px 6px -1px oklch(0% 0 0 / 0.1),
    0 10px 15px -3px oklch(0% 0 0 / 0.1);
}

/* Custom border radius */
.Card--rounded {
  border-radius: var(--space-6);
}

/* Custom padding */
.Card--tight {
  --card-padding: var(--space-3);
}

.Card--loose {
  --card-padding: var(--space-8);
}

/* Accent border */
.Card--accent {
  border-left: 4px solid var(--accent);
}

Theme Variants

/* Success card */
.Card--success {
  --card-bg: oklch(95% 0.04 150);
  --card-border: oklch(70% 0.15 150);
  border-left: 4px solid var(--card-border);
}

/* Warning card */
.Card--warning {
  --card-bg: oklch(95% 0.04 85);
  --card-border: oklch(75% 0.15 85);
  border-left: 4px solid var(--card-border);
}

/* Error card */
.Card--error {
  --card-bg: oklch(95% 0.04 25);
  --card-border: oklch(65% 0.2 25);
  border-left: 4px solid var(--card-border);
}

API Reference

Base Classes

Class Description
.Card Base card container (required)

Structure Classes

Class Description
.Card-header Card header section with title and actions
.Card-body Main content area with padding
.Card-footer Footer section for actions
.Card-image Image container at card top
.Card-overlay Text overlay on images

Typography Classes

Class Description
.Card-title Card heading text
.Card-subtitle Secondary heading or date
.Card-text Body text content
.Card-meta Metadata like timestamps or counts
.Card-tag Category or status tag
.Card-category Product/content category label

Variant Classes

Class Description
.Card--outlined Border only, no shadow
.Card--flat No border or shadow
.Card--filled Filled background, no shadow
.Card--interactive Clickable with hover effects
.Card--horizontal Side-by-side layout
.Card--overlay Text overlaid on image
.Card--pricing Pricing tier styling

Size Classes

Class Description
.Card--compact Reduced padding
.Card--spacious Increased padding

Stats Classes

Class Description
.Card-stat Large metric number
.Card-stat-label Metric label text
.Card-stat-change Change indicator
.Card-stat-change--positive Positive change (green)
.Card-stat-change--negative Negative change (red)

Pricing Classes

Class Description
.Card-price Price container
.Card-price-amount Large price number
.Card-price-period Billing period text
.Card-features Feature list container
.Card-feature Individual feature item
.Card-feature--disabled Unavailable feature (grayed)

Product Classes

Class Description
.Card-wishlist Wishlist heart button
.Card-rating Star rating container
.Card-rating-count Review count text
.Card-price-current Current sale price
.Card-price-original Original strikethrough price

Notification Classes

Class Description
.Card--notification Notification card base
.Card--notification-info Info notification (blue)
.Card--notification-success Success notification (green)
.Card--notification-warning Warning notification (yellow)
.Card--notification-error Error notification (red)

List Classes

Class Description
.Card-list List container inside card
.Card-list-item Individual list item
.Card-list-icon Icon container for list item
.Card-list-content Text content wrapper
.Card-list-title List item title
.Card-list-meta List item metadata

Layout Classes

Class Description
.CardGrid Responsive card grid container

CSS Reference

/* Base card */
.Card {
  background: var(--bg);
  border: 1px solid var(--bd);
  border-radius: var(--r-m);
  box-shadow: 0 1px 3px oklch(0% 0 0 / 0.08);
  overflow: hidden;
}

/* Structure */
.Card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4);
  border-bottom: 1px solid var(--bd);
}

.Card-body {
  padding: var(--space-4);
}

.Card-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4);
  border-top: 1px solid var(--bd);
}

.Card-image {
  width: 100%;
  background-size: cover;
  background-position: center;
}

/* Typography */
.Card-title {
  font-weight: 600;
  font-size: 1rem;
  color: var(--fg);
  margin-bottom: var(--space-1);
}

.Card-subtitle {
  font-size: 0.85rem;
  color: var(--fg-3);
}

.Card-text {
  font-size: 0.9rem;
  color: var(--fg-2);
  line-height: 1.5;
}

.Card-meta {
  font-size: 0.8rem;
  color: var(--fg-3);
}

.Card-tag {
  display: inline-block;
  padding: 2px var(--space-2);
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: var(--r-s);
  background: var(--accent);
  color: white;
}

/* Variants */
.Card--outlined {
  box-shadow: none;
}

.Card--flat {
  border: none;
  box-shadow: none;
  background: transparent;
}

.Card--filled {
  box-shadow: none;
  background: var(--bg-s);
}

.Card--interactive {
  cursor: pointer;
  transition: box-shadow 0.15s, transform 0.15s;
}

.Card--interactive:hover {
  box-shadow: 0 4px 12px oklch(0% 0 0 / 0.12);
  transform: translateY(-2px);
}

.Card--horizontal {
  display: flex;
}

.Card--horizontal .Card-image {
  width: auto;
  min-width: 140px;
}

/* Overlay */
.Card--overlay {
  position: relative;
}

.Card--overlay .Card-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: var(--space-4);
  background: linear-gradient(to top, oklch(0% 0 0 / 0.7), transparent);
  color: white;
}

.Card--overlay .Card-title,
.Card--overlay .Card-text {
  color: white;
}

/* Sizes */
.Card--compact .Card-body,
.Card--compact .Card-header,
.Card--compact .Card-footer {
  padding: var(--space-2) var(--space-3);
}

.Card--spacious .Card-body,
.Card--spacious .Card-header,
.Card--spacious .Card-footer {
  padding: var(--space-6);
}

/* Stats */
.Card-stat {
  display: block;
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--fg);
}

.Card-stat-label {
  display: block;
  font-size: 0.8rem;
  color: var(--fg-3);
  margin-top: var(--space-1);
}

.Card-stat-change {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  margin-top: var(--space-1);
}

.Card-stat-change--positive { color: oklch(55% 0.15 150); }
.Card-stat-change--negative { color: oklch(55% 0.2 25); }

/* Pricing */
.Card-price-amount {
  font-size: 2rem;
  font-weight: 700;
}

.Card-price-period {
  font-size: 0.85rem;
  color: var(--fg-3);
}

.Card-features {
  list-style: none;
  padding: 0;
  margin: 0;
}

.Card-feature {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) 0;
}

.Card-feature--disabled {
  color: var(--fg-3);
  text-decoration: line-through;
}

/* Product */
.Card-wishlist {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  background: white;
  border: none;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 1px 3px oklch(0% 0 0 / 0.15);
}

.Card-rating {
  display: flex;
  align-items: center;
  gap: 2px;
  color: oklch(70% 0.15 80);
  margin: var(--space-2) 0;
}

.Card-rating-count {
  font-size: 0.8rem;
  color: var(--fg-3);
  margin-left: var(--space-1);
}

.Card-price-current {
  font-weight: 700;
  font-size: 1.1rem;
}

.Card-price-original {
  text-decoration: line-through;
  color: var(--fg-3);
  font-size: 0.9rem;
  margin-left: var(--space-2);
}

/* Notification */
.Card--notification {
  border-left: 4px solid var(--bd);
}

.Card--notification-info { border-left-color: oklch(60% 0.15 250); }
.Card--notification-success { border-left-color: oklch(55% 0.15 150); }
.Card--notification-warning { border-left-color: oklch(70% 0.15 80); }
.Card--notification-error { border-left-color: oklch(55% 0.2 25); }

/* List */
.Card-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.Card-list-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--bd);
}

.Card-list-icon {
  width: 32px;
  height: 32px;
  border-radius: var(--r-s);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.Card-list-title {
  display: block;
  font-weight: 500;
  font-size: 0.9rem;
}

.Card-list-meta {
  display: block;
  font-size: 0.8rem;
  color: var(--fg-3);
}

/* Grid */
.CardGrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-4);
}

Accessibility

Semantic Structure

<!-- Use article for standalone content -->
<article class="Card">
    <div class="Card-body">
        <h3 class="Card-title">Article Title</h3>
        <p class="Card-text">Self-contained content.</p>
    </div>
</article>

<!-- Use heading hierarchy -->
<div class="Card">
    <div class="Card-header">
        <h2 class="Card-title">Section Title</h2>
    </div>
    <div class="Card-body">
        <h3>Subsection</h3>
        <p class="Card-text">Content under subsection.</p>
    </div>
</div>

Interactive Cards

<!-- Clickable card as link -->
<a href="/project" class="Card Card--interactive">
    <div class="Card-body">
        <h3 class="Card-title">Project Name</h3>
        <p class="Card-text">Click to view project details.</p>
    </div>
</a>

<!-- Card with multiple actions — don't make whole card clickable -->
<div class="Card">
    <div class="Card-body">
        <h3 class="Card-title">Project Name</h3>
        <p class="Card-text">Project description here.</p>
        <div class="Card-actions">
            <a href="/project/edit">Edit</a>
            <button>Delete</button>
        </div>
    </div>
</div>

Images

<!-- Decorative image -->
<div class="Card">
    <div class="Card-image" role="presentation" aria-hidden="true"
         style="background-image: url('pattern.jpg');"></div>
    <div class="Card-body">
        <h3 class="Card-title">Title</h3>
    </div>
</div>

<!-- Meaningful image -->
<div class="Card">
    <img class="Card-image" src="product.jpg" 
         alt="Blue wireless headphones with cushioned ear cups">
    <div class="Card-body">
        <h3 class="Card-title">Wireless Headphones</h3>
    </div>
</div>

Keyboard Navigation

Key Action
Tab Move focus to interactive elements
Enter Activate focused link or button
Space Activate focused button

Screen Reader Considerations

<!-- Price with context -->
<div class="Card-price-row">
    <span class="Card-price-current" aria-label="Sale price: $79.99">$79.99</span>
    <span class="Card-price-original" aria-label="Original price: $99.99">
        <s>$99.99</s>
    </span>
</div>

<!-- Stats with labels -->
<div class="Card-body">
    <span class="Card-stat" aria-describedby="stat-label-users">2,847</span>
    <span class="Card-stat-label" id="stat-label-users">Total Users</span>
</div>

<!-- Rating with text alternative -->
<div class="Card-rating" aria-label="4 out of 5 stars, 128 reviews">
    <i class="ph-fill ph-star" aria-hidden="true"></i>
    <i class="ph-fill ph-star" aria-hidden="true"></i>
    <i class="ph-fill ph-star" aria-hidden="true"></i>
    <i class="ph-fill ph-star" aria-hidden="true"></i>
    <i class="ph ph-star" aria-hidden="true"></i>
    <span class="Card-rating-count">(128)</span>
</div>

Best Practices

Do

  • Use consistent card heights in grids — align content or use CSS Grid
  • Limit content — Cards should be scannable, not essays
  • Single primary action — One clear CTA per card
  • Meaningful images — Images should add value, not just decoration
  • Clear visual hierarchy — Title → Supporting text → Actions
  • Group related cards — Use grids with consistent spacing

Don’t

  • Nest cards — Cards inside cards creates visual confusion
  • Too many actions — More than 2-3 actions clutters the card
  • Walls of text — Keep descriptions to 2-3 lines max
  • Inconsistent styling — Mix variants sparingly within a view
  • Click the whole card with multiple CTAs — Accessibility nightmare
  • Tiny touch targets — Ensure buttons/links are at least 44px

Content Guidelines

Titles: Keep to one line when possible. Be specific.

  • ✓ “Q4 Revenue Report”
  • ✗ “Report”

Descriptions: Front-load important info. Truncate gracefully.

  • ✓ “Revenue increased 12% driven by new enterprise clients.”
  • ✗ “In this quarter we saw various changes across multiple metrics…”

Actions: Use clear, specific verbs.

  • ✓ “View Report”, “Add to Cart”, “Start Trial”
  • ✗ “Click Here”, “Submit”, “Go”