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 (.xtyle-card__header / .xtyle-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
6 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
action when the card itself is the button). | ||||
role="button", a tab stop, and Enter/Space activation, so a JS onclick on the card is keyboard-reachable with no inner control. Implies the interactive hover lift, and its focus ring shows on keyboard entry only. Use it for a card that runs an action (open this item, select this row); for a card that navigates, use a link inside or CardLink. Do not put another interactive element inside an action card. | ||||
sm is a whisper, md (the default) an eased shadow, lg a pronounced lift. An interactive card bumps one step heavier on hover. |
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. A ::part() handle is reachable from your own stylesheet; the class beside it is the component's internal selector, which a shadow boundary keeps to itself.
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 xtyle-default register
(derive(xtyleDefault, { 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-0--elevation-1--elevation-2--elevation-3--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--yellowSlots
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.
<xtyle-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>
</xtyle-card>
<xtyle-card overlay compact>
<p>A compact card on a translucent overlay surface.</p>
</xtyle-card>
<xtyle-card interactive>
<h3 slot="header">Pricing</h3>
<p>See every plan and what is included.</p>
<a slot="footer" href="/pricing">View plans</a>
</xtyle-card><script lang="ts">
import { Card } from "@xtyle/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 "@xtyle/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>Action card
An action card is itself a keyboard-operable button: it focuses, Enter and Space fire its onclick, and the ring shows on keyboard entry only.
<xtyle-card action onclick="openProject('atlas')">
<h3 slot="header">Atlas</h3>
<p>Last edited 2 hours ago.</p>
</xtyle-card><script lang="ts">
import { Card } from "@xtyle/svelte";
let { openProject }: { openProject: (id: string) => void } = $props();
</script>
<Card action onclick={() => openProject("atlas")}>
{#snippet header()}<h3>Atlas</h3>{/snippet}
<p>Last edited 2 hours ago.</p>
</Card>---
import { Card } from "@xtyle/astro";
---
<Card action onclick="openProject('atlas')">
<h3 slot="header">Atlas</h3>
<p>Last edited 2 hours ago.</p>
</Card>