Karte

Eine Karte gruppiert zusammengehörigen Inhalt auf einer eigenen Fläche. Die Teile — cardHeader(), cardMedia(), cardBody(), cardFooter() — sind eigene Funktionen statt Props, du nimmst also nur die, die du brauchst, in der Reihenfolge, die das Design will.

Einfache Karte

Dateibasiertes Routing

src/about.ht.js → /about

Ordner werden zu Pfaden. Klammern werden zu Parametern. Es gibt keinen Router zu konfigurieren.

card(
  cardHeader({ title: 'Dateibasiertes Routing', subtitle: 'src/about.ht.js → /about' }),
  cardBody(text({ variant: 'small', tone: 'muted' }, 'Ordner werden zu Pfaden. Klammern werden zu Parametern. Es gibt keinen Router zu konfigurieren.')),
)

Varianten

Outlined ist der Standard. Elevated tauscht den Rahmen gegen einen Schatten, und flat tönt die Fläche statt beidem.

Outlined

Elevated

Flat

grid({ min: '13rem' },
  card({ variant: 'outlined' }, cardBody(text({ variant: 'small' }, 'Outlined'))),
  card({ variant: 'elevated' }, cardBody(text({ variant: 'small' }, 'Elevated'))),
  card({ variant: 'flat' }, cardBody(text({ variant: 'small' }, 'Flat'))),
)

divided setzt die Haarlinie über den Footer. Der Footer wird nach unten gedrückt, sodass Karten in einer Reihe ihre Aktionen auf einer Linie halten, auch wenn der Text darüber unterschiedlich lang ist.

Basis-Website

Ein minimales Projekt plus Deploy-Konfigurationen.

Markdown-Blog

Ein Ordner mit .md-Dateien, gerendert zu statischen Seiten, mit RSS-Feed und ganz ohne Client-JavaScript.

grid({ min: '14rem' },
  card(
    cardHeader({ title: 'Basis-Website' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'Ein minimales Projekt plus Deploy-Konfigurationen.')),
    cardFooter({ divided: true }, button({ size: 'sm', variant: 'soft' }, 'Öffnen')),
  ),
  card(
    cardHeader({ title: 'Markdown-Blog' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'Ein Ordner mit .md-Dateien, gerendert zu statischen Seiten, mit RSS-Feed und ganz ohne Client-JavaScript.')),
    cardFooter({ divided: true }, button({ size: 'sm', variant: 'soft' }, 'Öffnen')),
  ),
)

Medien

cardMedia() füllt den oberen Teil der Karte in festem Seitenverhältnis, sodass eine Reihe von Karten gleichmäßig bleibt, was auch immer die Quellbilder messen.

Standard 16 / 9

ratio: 4 / 3

grid({ min: '13rem' },
  card(
    cardMedia({ src: '/logo.svg', alt: '', style: 'background: var(--su-surface-2); object-fit: contain; padding: 1rem' }),
    cardBody(text({ variant: 'small' }, 'Standard 16 / 9')),
  ),
  card(
    cardMedia({ src: '/logo.svg', alt: '', ratio: '4 / 3', style: 'background: var(--su-surface-2); object-fit: contain; padding: 1rem' }),
    cardBody(text({ variant: 'small' }, 'ratio: 4 / 3')),
  ),
)

Gib der Karte ein href, und die ganze Fläche wird zu einem Link, samt dem Anheben beim Überfahren. Setze in dieser Form keine Buttons oder weiteren Links in eine Karte — interaktiver Inhalt darf nicht in einem Link stecken. Nimm stattdessen einen Footer-Button auf einer normalen Karte.

grid({ min: '14rem' },
  card({ href: '/de/docs/routing' },
    cardHeader({ title: 'Routing', subtitle: 'Zur Anleitung' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'Dynamische Routen, Catch-alls und Routengruppen.')),
  ),
  card({ href: '/de/docs/data' },
    cardHeader({ title: 'Daten laden', subtitle: 'Zur Anleitung' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'data() läuft zur Build-Zeit, mit Fetch-Caching.')),
  ),
)

Innenabstand

Eine Prop setzt den Innenabstand für alle Teile der Karte auf einmal.

padding: sm

padding: xl

stack({ gap: 'md' },
  card({ padding: 'sm' }, cardBody(text({ variant: 'small' }, 'padding: sm'))),
  card({ padding: 'xl' }, cardBody(text({ variant: 'small' }, 'padding: xl'))),
)

Freier Inhalt

Die Teile sind eine Bequemlichkeit, keine Pflicht — eine Karte nimmt beliebige Kinder, und cardHeader() nimmt neben dem Titel eigene Kinder auf, für einen Avatar oder einen Menü-Button rechts.

Paul Browne

Vor 4 Minuten deployt

PB
Build erfolgreich12 Seiten4,1 kB
card(
  cardHeader(
    { title: 'Paul Browne', subtitle: 'Vor 4 Minuten deployt' },
    avatar({ name: 'Paul Browne', size: 'sm' }),
  ),
  cardBody(
    stack({ direction: 'row', gap: 'sm', wrap: true },
      chip({ color: 'success', dot: true }, 'Build erfolgreich'),
      chip({ color: 'neutral' }, '12 Seiten'),
      chip({ color: 'neutral' }, '4,1 kB'),
    ),
  ),
)

Props

card():

PropTypStandardBeschreibung
variant'outlined' | 'elevated' | 'flat''outlined'Wie sich die Fläche von der Seite abhebt.
hrefstring—Rendert die ganze Karte als Link.
paddingSpace'lg'Innenabstand, den jedes Teil der Karte nutzt.

Die Teile:

TeilPropsStandardBeschreibung
cardHeadertitle, subtitle—Titel und Untertitel, plus beliebige Kinder daneben.
cardTitleas'h3'Der Titel für sich, wenn der Kopf von Hand gebaut wird.
cardSubtitle—Die gedämpfte Zeile unter einem Titel.
cardMediasrc, alt, ratio'16 / 9'Ein Titelbild in festem Seitenverhältnis.
cardBody—Der Hauptinhaltsbereich.
cardFooterdividedfalseUntere Aktionsreihe; divided setzt die Haarlinie darüber.