Skip to content

Card

A simple container for grouping related content.

Usage

A card is a simple container for grouping related content.
vue-html
<SCard>
  A card is a simple container for grouping related content.
</SCard>

header and footer are optional - each only renders (with its own separating border) when you actually pass it:

Delete project

This action cannot be undone. All data associated with this project will be permanently removed.
vue-html
<SCard>
  <template #header>
    <p class="font-semibold text-[var(--selaras-resolved-text-default)]">Delete project</p>
  </template>

  This action cannot be undone. All data associated with this project
  will be permanently removed.

  <template #footer>
    <div class="flex justify-end gap-2">
      <SButton variant="ghost">Cancel</SButton>
      <SButton color="danger">Delete</SButton>
    </div>
  </template>
</SCard>

Variant

outline

New feature shipped

Read the release notes for this week's update.

solid

New feature shipped

Read the release notes for this week's update.

soft

New feature shipped

Read the release notes for this week's update.

subtle

New feature shipped

Read the release notes for this week's update.

vue-html
<SCard variant="outline">
  <!-- bordered, no shadow -->
</SCard>
<SCard variant="solid">
  <!-- elevated, no border -->
</SCard>
<SCard variant="soft">
  <!-- subtle tinted background -->
</SCard>
<SCard variant="subtle">
  <!-- tinted background, plus a border -->
</SCard>

Blog post

A header badge and a footer byline, built entirely from other Selaras components:

Design

Building a scalable design token system

A look at how semantic tokens keep a component library themeable without ever touching a single component file.

JS

Jane Smith

Mar 12, 2026

vue-html
<SCard class="w-80">
  <template #header>
    <SBadge label="Design" color="primary" variant="soft" />
  </template>

  <h3 class="font-semibold text-[var(--selaras-resolved-text-default)]">
    Building a scalable design token system
  </h3>
  <p class="text-sm text-[var(--selaras-resolved-text-muted)]">
    A look at how semantic tokens keep a component library themeable
    without ever touching a single component file.
  </p>

  <template #footer>
    <div class="flex items-center gap-2">
      <SAvatar text="JS" size="sm" />
      <div class="text-sm leading-tight">
        <p class="font-medium text-[var(--selaras-resolved-text-default)]">Jane Smith</p>
        <p class="text-[var(--selaras-resolved-text-muted)]">Mar 12, 2026</p>
      </div>
    </div>
  </template>
</SCard>

Product

Overriding ui.body to p-0 lets a full-bleed image sit flush against the card's edges, with your own padded wrapper underneath for the details:

Wireless headphones

Wireless headphones

Noise-cancelling, 30-hour battery life

$129
vue-html
<SCard :ui="{ body: 'p-0' }" class="w-64">
  <img
    src="https://picsum.photos/seed/selaras-headphones/400/300"
    alt="Wireless headphones"
    class="aspect-[4/3] w-full object-cover"
  >
  <div class="flex flex-col gap-1 p-4">
    <p class="font-medium text-[var(--selaras-resolved-text-default)]">Wireless headphones</p>
    <p class="text-sm text-[var(--selaras-resolved-text-muted)]">Noise-cancelling, 30-hour battery life</p>
    <div class="mt-2 flex items-center justify-between">
      <span class="font-semibold text-[var(--selaras-resolved-text-default)]">$129</span>
      <SButton size="sm">Add to cart</SButton>
    </div>
  </div>
</SCard>

In markdown

Every Selaras component is already globally registered under its S-prefixed name - a bare ::s-card{...} block works with no extra wiring (see Callout's own "In markdown" section for how the pattern works generally). Its header/footer named slots are each a #slot-name line inside the block, @nuxtjs/mdc's own convention:

text
::s-card
#header
Design
#footer
Posted March 2026
::

A block mixing header/footer markers with unmarked body text for the default slot doesn't reliably separate the two - confirmed empirically, not just undocumented - so keep a markdown-authored card to its named slots only; reach for <SCard> directly in a .vue file once the body needs its own text.

Custom :ui

Global and scoped recipe overrides use ui.card.

To see exactly what you'd be overriding - the current default classes for every slot and variant - here's Card's own theme file:

Theme source "card" not found

Props

PropTypeDefault
variant'outline' | 'solid' | 'soft' | 'subtle''outline'
uiPartial<Record<CardSlot, string | object>>-

Slots

SlotDescription
headerOptional content above the body, separated by a border. Only rendered when passed.
defaultThe card's body content.
footerOptional content below the body, separated by a border. Only rendered when passed.
Edit this page