Card
Card is the compact one-child surface for related content. CardLayout is the
sectioned form for product cards with a header, body, footer, and optional
separator insets.
Use a card to make a meaningful group easier to scan. Do not put every row in a
card: when every element becomes a separate surface, hierarchy disappears.
Compact card
use fission::prelude::*;
let summary: Widget = Card {
child: VStack {
spacing: Some(8.0),
children: vec![
Text::new("Billing").into(),
Text::new("Next invoice: 15 May").into(),
],
}
.into(),
pattern: CardPattern::Plain,
interactive: false,
selected: false,
}
.into();
Card applies the resolved surface padding around its single child.
Sectioned card anatomy
use fission::prelude::*;
let settings: Widget = CardLayout::new()
.header(
CardHeader::new(CardTitle::new("Notifications"))
.description(CardDescription::new(
"Choose how the team can reach you.",
))
.action(notification_menu),
)
.content(CardContent::new(notification_form))
.footer(CardFooter::new(vec![cancel_button, save_button]))
.separated(true)
.size(ComponentSize::Md)
.pattern(CardPattern::Raised)
.interactive(false)
.selected(false)
.separator_inset(16.0)
.into();
| |
|---|
| Owns one card surface and arranges the optional regions in header, content, footer order. |
| Arranges a flexible heading group beside an optional, top-aligned trailing action. Use new/description for standard regions or custom/custom_description for retained widgets. |
| Applies the active primary text and medium-weight body typography to a standard title. |
| Applies the active secondary text and regular body typography to supporting copy. |
| Applies the card's region padding without changing the supplied body widget. |
| Applies region padding and arranges action children in a compact, end-aligned row beneath one optional top boundary. |
Use CardTitle and CardDescription for the standard treatment. Start with
CardHeader::custom(...) and use .custom_description(...) when the heading
needs badges, status, richer text, or a different semantic heading structure.
Regions own their padding so separators can span the complete surface width or
use a consistent inset without negative margins or nested cards.
Field reference
Card fields:
| | | |
|---|
| | The one retained child inside the padded surface. | |
| | Design-system surface pattern. | |
| | Allows the design system's real-hover recipe to appear. | false. It does not add an action or focus behavior. |
| | Applies the design system's controlled selected treatment. | false. It does not add selection behavior. |
CardLayout fields and builders:
| | | |
|---|
| | Optional heading and trailing-action region. | |
| | Optional primary content region. | |
| | Optional end-aligned action region. | |
| | Enables the shared divider between adjacent regions when no footer-specific boundary applies. | true; an explicit footer recipe boundary remains part of the footer treatment. |
| | Shared density for region padding, gaps, and standard title/description typography. | Md; the default design also defines Sm, and unsupported slots fall back to Md. |
| | The same surface treatment used by Card. | |
| | Allows the hover recipe while the card is actually hovered. | |
| | Applies the controlled selected recipe to the surface. | |
| | Overrides every region boundary with one symmetric horizontal inset. | None; each boundary uses its design-system recipe margin. |
CardPattern provides Plain, Raised, Tinted, and Elevated. The default
design keeps Raised flat; choose Elevated when rest elevation is part of the
intended hierarchy. A custom DSP can give any pattern a different recipe.
Design-system, interaction, and semantics
Both APIs resolve the same theme.components.card recipe. Background, border,
radius, padding, and every shadow layer come from the chosen pattern, with the
hover recipe layered only while interactive is true and the pointer is really
over the card. The selected recipe is layered independently when selected is
true, so controlled selection remains visible during hover. Named-region
background, gap, typography, padding, and separator recipes remain
design-system controlled. The surface clips its content to the resolved radius.
Each present region owns its density padding. Separator margins come from the
active recipe unless separator_inset supplies one consistent layout-specific
override. A footer recipe border is interpreted as one top boundary rather than
a four-sided inset border. When that footer boundary is absent, a separated
layout falls back to the shared section-separator recipe. This always produces
exactly one boundary above the footer. With shared separators disabled,
CardLayout uses the density gap between regions, preserves outer vertical
padding, and keeps region-specific horizontal padding; an explicit footer
boundary in the active recipe remains part of the footer treatment.
interactive is visual feedback, not activation. A card does not become a
button, receive focus, or dispatch an action merely because that flag is true.
Likewise, selected is controlled presentation; the owner remains responsible
for changing selection state.
Compose it with Pressable or a more specific control when the whole surface
represents an action, and give that control an
accessible name. The card surface adds no semantic role of its own; text,
controls, and any explicit semantic regions supplied inside it retain theirs.
Responsive and target behavior
Cards impose no fixed width. They follow parent constraints, while their region
padding remains design-system controlled. The standard footer remains a row;
if actions need to stack on a narrow screen, pass a responsive retained layout
as the footer's child rather than duplicating the card surface.
The footer's End alignment is logical: it mirrors with the active layout
direction while retained source and keyboard order remain unchanged. Paragraph
bidi and shaping remain a separate TextDirection concern.
Cards register no widget-owned motion. Any Motion, Presence, or ripple
behavior composed around or inside one still follows the global
Env::motion_preference, so a card does not need its own preference branch.
Their layout and paint lower through the shared target model. Static site and
SSR can render the same surface and content, while actions composed inside it
still need the corresponding interactive runtime or browser island.
Production checklist
Choose the pattern from information hierarchy, not decoration alone.
Use CardLayout when regions need independent composition or separators; do
not nest several Card values to imitate one sectioned card.
Treat interactive as hover presentation only and add a semantic input
widget for activation.
Test long headings, translated descriptions, custom header actions, and
footer actions at the narrowest supported width.
Give repeated or reorderable cards a stable explicit widget identity derived
from durable data.