Card
A surface with a header, a body and a footer — six exported parts, and none of them an affordance.
import { Card, CardHeader, CardContent, CardFooter } from "@glint/components/card.slint";import { Button, ButtonVariant } from "@glint/components/button.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { width: 420px;
Card { CardHeader { title: "Create project"; description: "Deploy your new project in one-click."; }
CardContent { Text { text: "Your framework will be automatically detected and configured."; color: Tokens.color-muted-foreground; font-size: Tokens.typography-body-sm-size; } }
CardFooter { Button { text: "Cancel"; variant: ButtonVariant.ghost; }
Button { text: "Deploy"; } } } } } }}Usage
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "@glint/components/card.slint";import { Button } from "@glint/components/button.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component AppWindow inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
Card { CardHeader { title: "Notifications"; description: "Choose what notifications you receive."; }
CardContent { Text { text: "Configure push, email, and SMS alert channels."; color: Tokens.color-foreground; } }
CardFooter { Button { text: "Save preferences"; } } } }}Card serves as a surface container. Its companion helpers (CardHeader, CardTitle, CardDescription, CardContent, CardFooter) establish clean information hierarchy.
Examples
Variants
Cards support CardVariant.solid, CardVariant.glass, CardVariant.glass-interactive, and CardVariant.raised.
import { Card, CardVariant, CardHeader, CardContent } from "@glint/components/card.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center; spacing: 16px;
VerticalLayout { width: 220px; spacing: 16px;
Card { variant: CardVariant.solid; CardHeader { title: "Solid"; description: "Standard card surface"; } }
Card { variant: CardVariant.glass; CardHeader { title: "Glass"; description: "Translucent backdrop"; } } }
VerticalLayout { width: 220px; spacing: 16px;
Card { variant: CardVariant.glass-interactive; CardHeader { title: "Interactive"; description: "Responds to hover"; } }
Card { variant: CardVariant.raised; CardHeader { title: "Raised"; description: "Elevated elevation shadow"; } } } } }}Sizes
Use size: CardSize.sm for compact lists or sidebars, and size: CardSize.default for full content sections.
import { Card, CardSize, CardHeader, CardContent } from "@glint/components/card.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 260px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center; spacing: 16px;
VerticalLayout { width: 220px;
Card { size: CardSize.sm;
CardHeader { title: "Compact card"; description: "Reduced padding and gaps."; } } }
VerticalLayout { width: 240px;
Card { size: CardSize.default;
CardHeader { title: "Default card"; description: "Standard spacious layout."; } } } } }}Padding overrides
Override internal container padding using card-padding: CardPadding.none, CardPadding.sm, CardPadding.md, or CardPadding.lg.
import { Card, CardPadding, CardHeader, CardContent } from "@glint/components/card.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center; spacing: 16px;
VerticalLayout { width: 220px;
Card { card-padding: CardPadding.sm; CardHeader { title: "Small padding"; } } }
VerticalLayout { width: 220px;
Card { card-padding: CardPadding.lg; CardHeader { title: "Large padding"; } } } } }}Radius overrides
Customize corner roundness with card-radius: CardRadius.md, CardRadius.lg, CardRadius.xl, or CardRadius.xxl.
import { Card, CardRadius, CardHeader } from "@glint/components/card.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center; spacing: 16px;
VerticalLayout { width: 220px;
Card { card-radius: CardRadius.md; CardHeader { title: "Medium radius"; } } }
VerticalLayout { width: 220px;
Card { card-radius: CardRadius.xxl; CardHeader { title: "2XL radius"; } } } } }}Title and description type
CardTitle is a Heading and CardDescription is
a Body, so both take the type ladder’s own knobs: tone picks the color role
on either, level steps the heading, and size steps the description.
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@glint/components/card.slint";import { BodySize, TypographyTone } from "@glint/components/typography.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { width: 340px;
Card { CardHeader { CardTitle { text: "Payment failed"; level: 3; tone: TypographyTone.danger; }
CardDescription { text: "We could not charge the card ending 4242."; size: BodySize.sm; tone: TypographyTone.muted; } }
CardContent { Text { text: "Update the card to keep the workspace active."; color: Tokens.color-foreground; font-size: Tokens.typography-body-sm-size; wrap: word-wrap; } } } } } }}API Reference
Properties
| Property | Type | Default | Description |
|---|---|---|---|
variant | in CardVariant | CardVariant.solid | Surface treatment — solid, glass, glass-interactive, raised. |
size | in CardSize | CardSize.default | Density — the padding around the content and the gap between its sections, together. A compact card is one word (ADR-0022). |
card-padding | in CardPadding | CardPadding.auto | Padding override — auto (follow size), none, sm, md, lg. Reach for none when the content draws to the border: a full-bleed strip of media or a table, which is not a density choice at all. |
card-radius | in CardRadius | CardRadius.xl | Corner radius override — md, lg, xl, xxl. |
hovered | out bool | no default | Read-only hover signal — driven by the internal TouchArea below. Consumers can read it (e.g. to drive header chip styling) but never set it. |
padding-l | out length | no default | Both lengths come off size, and card-padding overrides one of them (none/sm/md/lg → 0/12/16/24). The column below applies both. They stay published for content that has to draw to the card's edge — a strip of media, a full-bleed table — and therefore needs to know what it is escaping (MessageBubble's rule). |
gap-l | out length | no default | Resolved gap between header / content / footer in px; outbound. |
Enums
| Enum | Values |
|---|---|
CardVariant | solid, glass, glass-interactive, raised |
CardSize | sm, default |
CardPadding | auto, none, sm, md, lg |
CardRadius | md, lg, xl, xxl |
CardHeader
The top band: the title and description stack on the left, and the trailing
place is kept for the control that acts on the card — the @children slot. A
header written without one pays nothing for it.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
title | in string | no default | Heading of the card. |
description | in string | no default | Line under the title; empty hides it. |
CardTitle
The header’s own heading style, exported for a title that is not inside a
CardHeader. level is a step on the type ladder rather than an outline
level — see Typography.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
level | in int | 1 | Which step, 1 (largest) through 5 (smallest). Out-of-range levels take the smallest step rather than drawing nothing. |
tone | in TypographyTone | TypographyTone.default | Colour role — default, muted, subtle. |
Enums
| Enum | Values |
|---|---|
TypographyTone | default, muted, subtle, accent, danger |
CardDescription
The line under the title, at the muted tone and wrapping by word.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
size | in BodySize | BodySize.default | Which step — lg, default, sm, label, caption. |
tone | in TypographyTone | TypographyTone.default | Colour role — default, muted, subtle. |
Enums
| Enum | Values |
|---|---|
BodySize | lg, default, sm, label, caption |
TypographyTone | default, muted, subtle, accent, danger |
CardContent
The body of the card.
CardContent publishes no properties, callbacks or functions of its own. What a call site can set on it is the Slint VerticalLayout it inherits.
CardFooter
The row of actions along the bottom, aligned to the end.
CardFooter publishes no properties, callbacks or functions of its own. What a call site can set on it is the Slint HorizontalLayout it inherits.
Accessibility
- The surface carries no role and takes no name. A card is a container, and
Glint gives it no node in the accessibility tree: what a screen reader reads
is what you put inside it. A card that is itself one target — a whole tile
that opens something — is a
Buttonwrapping the content, not aCardwith a click handler. CardTitleis a size, not an outline level. Itslevel: 5picks a step on the type ladder (Typography) and nothing more:Headinginherits Slint’sTextand declares noaccessible-role, so no heading node reaches the tree and no reading order is built from it. A screen reader hears the title as text in the order it is laid out. Where a card opens a region a reader needs to jump to, name that region at the call site —accessible-role: regionandaccessible-labeltogether, the way ScrollArea documents.- The controls inside are the accessible part. A
Buttonin aCardHeaderor aCardFooterkeeps its own role, name, focus ring and default action; the card neither adds to that nor gets in its way.