Documentation

Documentation

Card

Slot-composed content container with media, badge, heading, feature, and footer regions.

The <dsgn-card> component groups related content in a bordered or elevated <article>. It is composed entirely from named slots — media at the top, then a badge, a heading, an optional list of feature rows, and a footer. The badge and heading regions are omitted when empty; the media and footer regions always reserve their spacing, so a card with no footer still renders its top border.

Usage

<dsgn-card variant="elevated" padding="md">
  <span slot="heading">Card heading</span>
  <dsgn-button slot="footer" appearance="outline">Learn more</dsgn-button>
</dsgn-card>

Import the component module in your application entrypoint:

import '@ds-gn/ui/card';

Playground

Props

Prop Type Default Description
variant 'elevated' | 'outlined' 'outlined' Visual treatment: a shadowed surface or a bordered one.
padding 'none' | 'sm' | 'md' | 'lg' 'md' Internal padding. none lets media run to the card edge.
surface 'light' | 'dark' 'light' Semantic token surface to use. It is passed down to rendered feature rows.
features CardFeature[] [] Feature rows rendered in the card body. Property-only (no attribute).

There is no default variant and no interactive prop. For a clickable card, put a link or a <dsgn-button> in the footer slot.

Slots

Slot Description
media Card media, rendered above everything else.
badge Badge content above the heading. The region is omitted when empty.
heading Card heading. The region is omitted when empty.
footer Card footer content.

The card has no default slot. Unslotted children are not rendered — body content belongs in features, and anything else belongs in one of the named slots.

Features

features is a JavaScript property, so it is set from script rather than markup. Each entry renders a <dsgn-feature-item> with an optional bullet list:

interface CardFeature {
  label: string;
  variant: 'default' | 'brand' | 'accent' | 'success' | 'warning' | 'error';
  icon?: SVGTemplateResult;
  bullets?: string[];
}
import { check } from '@ds-gn/ui/icon/icons';

const card = document.querySelector('dsgn-card');
card.features = [
  { label: 'Unlimited projects', variant: 'success', icon: check },
  {
    label: 'Team access',
    variant: 'brand',
    bullets: ['Up to 10 seats', 'Shared token themes'],
  },
];

Feature rows inherit the card’s surface, so they stay legible when the card is placed on a dark background.

Examples

Variants

<dsgn-card variant="outlined"><span slot="heading">Outlined</span></dsgn-card>
<dsgn-card variant="elevated"><span slot="heading">Elevated</span></dsgn-card>

Media card

<dsgn-card variant="elevated" padding="none">
  <dsgn-image
    slot="media"
    src="/preview.png"
    alt="Product screenshot"
    aspect="video"
  ></dsgn-image>
  <dsgn-badge slot="badge" variant="brand">New</dsgn-badge>
  <dsgn-heading slot="heading" heading-size="h3">Release preview</dsgn-heading>
</dsgn-card>

Padding

<dsgn-card padding="sm"><span slot="heading">Compact</span></dsgn-card>
<dsgn-card padding="md"><span slot="heading">Standard</span></dsgn-card>
<dsgn-card padding="lg"><span slot="heading">Spacious</span></dsgn-card>

On a dark surface

<dsgn-card surface="dark" variant="outlined">
  <dsgn-heading slot="heading" surface="dark" heading-size="h3"
    >Dark card</dsgn-heading
  >
</dsgn-card>

Usage patterns

  • Pair padding="none" with a media slot when the image should bleed to the card’s edges; keep md when the card is text-only.
  • Set the same surface on the card and on the components you slot into it — slotted content is styled by its own element, not by the card.
Esc