Card

Flexible card component for content containers

Overview

The s-card attribute provides a structured container for content with optional header, body, and footer sections.

Import

/* Full framework (includes all components) */
@import "@shift-css/core";

/* Or import just the card component */
@import "@shift-css/core/components/card";

Note: When importing individual components, you also need @shift-css/core/reset and @shift-css/core/tokens for the base styles and design tokens.

Basic Cards

Card with header, body, and footer

Card with Header

Card body content goes here.

Card Title

Card subtitle text

Using semantic title/subtitle attributes.

<div class="demo-grid">
<article s-card>
  <header s-card-header>
    <strong style="display: block; margin: 0;">Card with Header</strong>
  </header>
  <div s-card-body>
    <p style="margin: 0;">Card body content goes here.</p>
  </div>
  <footer s-card-footer>
    <button s-btn="primary" s-size="sm">Action</button>
  </footer>
</article>
<article s-card>
  <div s-card-body>
    <p s-card-title>Card Title</p>
    <p s-card-subtitle>Card subtitle text</p>
    <p style="margin: 0;">Using semantic title/subtitle attributes.</p>
  </div>
</article>
</div>

Media Card

Card with image

Abstract gradient

Media Card

With image container

Using s-card-media for 16:9 images.

Abstract art

Horizontal Card

Side-by-side layout

Using s-horizontal modifier.

<div class="demo-grid">
<article s-card>
  <div s-card-media>
    <img
      src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=400&h=225&fit=crop"
      alt="Abstract gradient"
      width="400"
      height="225"
    />
  </div>
  <div s-card-body>
    <p s-card-title>Media Card</p>
    <p s-card-subtitle>With image container</p>
    <p style="margin: 0;">Using <code>s-card-media</code> for 16:9 images.</p>
  </div>
</article>
<article s-card s-horizontal>
  <div s-card-media>
    <img
      src="https://images.unsplash.com/photo-1557672172-298e090bd0f1?w=200&h=200&fit=crop"
      alt="Abstract art"
      width="200"
      height="200"
    />
  </div>
  <div s-card-body>
    <p s-card-title>Horizontal Card</p>
    <p s-card-subtitle>Side-by-side layout</p>
    <p style="margin: 0;">Using <code>s-horizontal</code> modifier.</p>
  </div>
</article>
</div>

Card Variants

Elevation variants

Flat Card

s-card="flat"

Elevated Card

s-card="elevated"

Outline Card

s-card="outline"

<div class="demo-grid">
<article s-card="flat">
  <div s-card-body>
    <strong style="display: block; margin: 0 0 var(--s-space-2);">Flat Card</strong>
    <p style="margin: 0; font-size: var(--s-text-sm);"><code>s-card="flat"</code></p>
  </div>
</article>
<article s-card="elevated">
  <div s-card-body>
    <strong style="display: block; margin: 0 0 var(--s-space-2);">Elevated Card</strong>
    <p style="margin: 0; font-size: var(--s-text-sm);"><code>s-card="elevated"</code></p>
  </div>
</article>
<article s-card="outline">
  <div s-card-body>
    <strong style="display: block; margin: 0 0 var(--s-space-2);">Outline Card</strong>
    <p style="margin: 0; font-size: var(--s-text-sm);"><code>s-card="outline"</code></p>
  </div>
</article>
</div>

Interactive Card

Hoverable card with lift effect

Hover Me!

s-interactive adds lift on hover.

<article s-card s-interactive>
<div s-card-body>
  <strong style="display: block; margin: 0 0 var(--s-space-2);">Hover Me!</strong>
  <p style="margin: 0; font-size: var(--s-text-sm);"><code>s-interactive</code> adds lift on hover.</p>
</div>
</article>

Card Sections

Attribute Purpose
s-card Main card container
s-card-header Card header area
s-card-body Main content area
s-card-footer Footer with actions
s-card-media Image/media container
s-card-title Card title text
s-card-subtitle Subtitle/description

Examples

Simple Card

<article s-card>
  <div s-card-body>
    <h4>Simple Card</h4>
    <p>Just a body section with content.</p>
  </div>
</article>

Card with All Sections

<article s-card>
  <header s-card-header>
    <h3>Project Update</h3>
  </header>
  <div s-card-body>
    <p>The project is progressing well with all milestones on track.</p>
  </div>
  <footer s-card-footer>
    <button s-btn="ghost" s-size="sm">Cancel</button>
    <button s-btn="primary" s-size="sm">View Details</button>
  </footer>
</article>

Make the entire card clickable:

<article s-card s-link s-interactive>
  <div s-card-body>
    <h4 s-card-title>
      <a href="/details">Clickable Card</a>
    </h4>
    <p>Click anywhere on the card.</p>
  </div>
</article>

Card Layouts

Card Grid

Responsive grid with auto-fitting columns:

<div s-card-grid>
  <article s-card>
    <div s-card-body>Card 1</div>
  </article>
  <article s-card>
    <div s-card-body>Card 2</div>
  </article>
  <article s-card>
    <div s-card-body>Card 3</div>
  </article>
</div>

Card Stack

Vertical list of cards:

<div s-card-stack>
  <article s-card>
    <div s-card-body>Stacked card 1</div>
  </article>
  <article s-card>
    <div s-card-body>Stacked card 2</div>
  </article>
</div>

How It Works

Cards use CSS custom properties for consistent styling:

:where([s-card]) {
  --_card-bg: var(--s-surface-raised);
  --_card-border: var(--s-border-muted);
  --_card-radius: var(--s-radius-xl);
  --_card-padding: var(--s-space-4);

  background-color: var(--_card-bg);
  border: 1px solid var(--_card-border);
  border-radius: var(--_card-radius);
}

:where([s-card-body]) {
  padding: var(--_card-padding);
}

All Attributes

Attribute Purpose Values
s-card Card variant (default), flat, elevated, outline, feature
s-card-header Header section N/A
s-card-body Body section N/A
s-card-footer Footer section N/A
s-card-media Media container N/A
s-card-title Title element N/A
s-card-subtitle Subtitle element N/A
s-interactive Hover lift effect Boolean
s-horizontal Horizontal layout Boolean
s-link Link overlay Boolean
s-size Card size sm, lg
s-card-grid Grid container N/A
s-card-stack Stack container N/A

Customization Examples

Custom Background

<article s-card style="--_card-bg: var(--s-primary-50);">
  <div s-card-body>Tinted card background</div>
</article>

Sharp Corners

[s-card] {
  --_card-radius: 0;
}
Search