Card
A surface container that groups related content, with optional header and footer regions.
Live demo
Card is the workhorse surface: a bordered, elevated panel that frames related content as one unit. It lays its three regions (header, body, footer) out in a column with consistent spacing; the header and footer are real light-DOM parts (.xoji-card__header / .xoji-card__footer), so the same structure renders identically across every binding.
An overlay variant swaps the surface for the translucent treatment used inside popovers and menus; a compact size tightens the padding; an interactive variant adds a hover elevation lift plus a focus-within ring for cards that act as a single clickable target. That last one is presentational only: it styles the surface but adds no behavior, so the consumer wraps the clickable content in a real <button> or <a> for keyboard and screen-reader semantics.
When to use
How this component composes with the rest of the set.
Props
4 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Appearance
Variants
default
The standard elevated surface on the raised background.
overlay
The translucent overlay surface, for cards floating over other content.
interactive
Hover elevation lift plus a focus-within ring for a clickable card.
Sizes
default
Standard padding.
compact
Tightened padding and spacing.
States
hover
Pointer over an interactive card; the surface lifts and the overlay paints the hover tint.
active
Interactive card pressed; the lift drops and the overlay paints the press tint.
focus-within
Keyboard focus lands inside an interactive card: a token-colored ring, plus a transparent outline that becomes real in forced-colors mode.
Anatomy
The named parts that make up the component, with their selectors.
card
The surface container carrying the variant and size classes.
header
The top region, a heading-weight title for the card.
body
The main content region.
footer
The bottom region: separated by a top border, drawn in muted ink.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xoji-default register
(derive(xojiDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--accent
--accent-2
--accent-3
--accent-4
--bg-1
--black
--blue
--border-normal
--border-thick
--border-thin
--brown
--cyan
--danger
--duration-fast
--ease-standard
--elevation-2
--elevation-4
--fg-0
--fg-1
--fg-2
--font-sans
--gray
--green
--info
--leading-normal
--leading-tight
--line
--line-2
--neutral
--orange
--pink
--purple
--radius-lg
--red
--ring
--space-1
--space-2
--space-3
--space-4
--space-5
--state-hover
--state-press
--success
--surface-overlay
--surface-overlay-border
--text-body
--text-lg
--warn
--weight-semibold
--white
--yellow
Slots
The card body content.
The card title region, rendered above the body.
The card footer region, rendered below the body with a top border.
Accessibility
Code
Regions and variants
Header, body, and footer regions; the overlay, compact, and interactive variants.
<xoji-card>
<h3 slot="header">Monthly report</h3>
<p>Revenue is up 12% over last month, driven by the new onboarding flow.</p>
<div slot="footer">Updated 2 hours ago</div>
</xoji-card>
<xoji-card overlay compact>
<p>A compact card on a translucent overlay surface.</p>
</xoji-card>
<xoji-card interactive>
<h3 slot="header">Pricing</h3>
<p>See every plan and what is included.</p>
<a slot="footer" href="/pricing">View plans</a>
</xoji-card>
<script lang="ts">
import { Card } from "@xoji/svelte";
</script>
<Card>
{#snippet header()}<h3>Monthly report</h3>{/snippet}
<p>Revenue is up 12% over last month, driven by the new onboarding flow.</p>
{#snippet footer()}Updated 2 hours ago{/snippet}
</Card>
<Card overlay compact>
<p>A compact card on a translucent overlay surface.</p>
</Card>
<Card interactive>
{#snippet header()}<h3>Pricing</h3>{/snippet}
<p>See every plan and what is included.</p>
{#snippet footer()}<a href="/pricing">View plans</a>{/snippet}
</Card>
---
import { Card } from "@xoji/astro";
---
<Card>
<h3 slot="header">Monthly report</h3>
<p>Revenue is up 12% over last month, driven by the new onboarding flow.</p>
<div slot="footer">Updated 2 hours ago</div>
</Card>
<Card overlay compact>
<p>A compact card on a translucent overlay surface.</p>
</Card>
<Card interactive>
<h3 slot="header">Pricing</h3>
<p>See every plan and what is included.</p>
<a slot="footer" href="/pricing">View plans</a>
</Card>