Layout

Card

A versatile container with optional header, body, and footer sections. Ideal for grouping related content with consistent styling.

Playground

Experiment with different props in real-time.

Card Title

A short description

This is the body content of the card. It can contain any elements.

Basic Usage

Place content directly inside the card for the body section.

This is a basic card with body content.

<script lang="ts">
  import { Card } from 'sv5ui';
</script>

<Card>
  <p>This is a basic card with body content.</p>
</Card>

Variants

4 visual styles.

outline

soft

subtle

solid

<Card variant="outline">Outline card</Card>
<Card variant="soft">Soft card</Card>
<Card variant="subtle">Subtle card</Card>
<Card variant="solid">Solid card</Card>

Header & Footer

Use header and footer snippets for structured layouts.

Card Title

Subtitle or description

This is the body content of the card.

<Card>
  {#snippet header()}
    <h3 class="text-lg font-semibold">Card Title</h3>
    <p class="text-on-surface/60 text-sm">Subtitle or description</p>
  {/snippet}

  <p>This is the body content of the card.</p>

  {#snippet footer()}
    <div class="flex justify-end gap-2">
      <Button variant="ghost">Cancel</Button>
      <Button variant="solid">Save</Button>
    </div>
  {/snippet}
</Card>

Header Only

Use just a header snippet with body content.

Notifications

You have 3 unread messages.

<Card>
  {#snippet header()}
    <h3 class="text-lg font-semibold">Notifications</h3>
  {/snippet}
  <p>You have 3 unread messages.</p>
</Card>

Footer Only

Use just a footer snippet for action-oriented cards.

Are you sure you want to delete this item?

<Card>
  <p>Are you sure you want to delete this item?</p>
  {#snippet footer()}
    <div class="flex justify-end gap-2">
      <Button variant="outline">Cancel</Button>
      <Button variant="solid" color="error">Delete</Button>
    </div>
  {/snippet}
</Card>

Custom Element

Render the card as a different HTML element with the as prop.

section

article

<!-- Render as different HTML elements -->
<Card as="section">Section card</Card>
<Card as="article">Article card</Card>
<Card as="aside">Aside card</Card>

UI Slots

Use the ui prop to override classes on internal elements.

SlotDescription
rootCard container — controls border, background, overflow
headerHeader section — controls padding
bodyBody section — controls padding for children content
footerFooter section — controls padding

Custom Styled

Body content with larger text
<Card
  ui={{
    root: 'shadow-lg',
    header: 'bg-primary/5',
    body: 'text-lg',
    footer: 'bg-surface-container/50'
  }}
>
  {#snippet header()}
    <h3 class="font-semibold">Custom Styled</h3>
  {/snippet}
  Body content with larger text
  {#snippet footer()}
    <Button>Action</Button>
  {/snippet}
</Card>
Image Placeholder

Image Card

Edge-to-edge image with custom body padding.

<!-- Remove default padding for edge-to-edge content -->
<Card ui={{ body: 'p-0' }}>
  <img src="/placeholder.jpg" alt="Cover" class="h-48 w-full object-cover" />
  <div class="p-4">
    <h3 class="font-semibold">Image Card</h3>
    <p class="text-on-surface/60 text-sm">Edge-to-edge image with custom body padding.</p>
  </div>
</Card>

Snippets

Use Svelte 5 snippets to populate the header and footer sections.

SnippetDescription
headerContent rendered in the card header section
childrenDefault body content (implicit — direct children of Card)
footerContent rendered in the card footer section

Props

PropTypeDefault
variant'solid' | 'outline' | 'soft' | 'subtle''outline'
askeyof HTMLElementTagNameMap'div'
refHTMLElement | nullnull
classstring-
uiRecord<Slot, Class>-