Card
Content & statusBrick 0.1.12

Card

Card is a static compound surface for grouping information and related actions about one subject.

Live example

Built from the published package

Interactive

Quarterly report

Updated five minutes ago

Conversion improved across every checkout step.
Choose with confidence

Know when Card is the right part

Use it when

Use Card for summaries, settings groups, product or article previews, metrics, profiles, and other reusable content units that benefit from a visible surface and optional header, supporting description, body, or footer.

Card owns visual grouping and content anatomy. Use application Container, Stack, Grid, or ordinary CSS to control its width, height, position, and page-level responsive layout.

Choose another path when

  • Use semantic HTML or layout primitives when no visual surface is needed.
  • Use Alert for status messaging.
  • Use Dialog, Popover, Drawer, or HoverCard for temporary content.
  • Use Button or Link for an action rather than adding click behavior to a generic Card.
  • Build complete sections and data-driven blocks above Brick.

Installation and imports

Import Card from the package root or stable component subpath and import the required stylesheet once at the application root:

tsx
import { Card } from "@flowstack-ui/brick/card";
import "@flowstack-ui/brick/styles.css";

The complete stylesheet above is the recommended default. For a measured route-aware build, replace it with the shared foundation and this component's stylesheet:

tsx
import "@flowstack-ui/brick/styles/core.css"; // once at the application root
import "@flowstack-ui/brick/styles/card.css";

Add the modular stylesheet for every other Brick component the route renders. Do not combine modular styles with styles.css or tokens.css.

Card and its public types are also exported from @flowstack-ui/brick.

Quick start

tsx
<Card.Root as="article" aria-labelledby="report-title">
  <Card.Header>
    <Card.Title as="h2" id="report-title">Quarterly report</Card.Title>
    <Card.Description>Updated five minutes ago</Card.Description>
  </Card.Header>
  <Card.Content>Conversion improved across every checkout step.</Card.Content>
  <Card.Footer>
    <Button>Open report</Button>
  </Card.Footer>
</Card.Root>

Visual recipes and states

Variants

  • outline is the default clear boundary and does not depend on shadow.
  • elevated uses a restrained shadow plus a faint boundary for higher prominence.
  • subtle uses a quiet filled surface without shadow.

Card has no hover, pressed, selected, loading, disabled, focus, or tone state. Those belong to the explicit components inside it.

Sizes

sm, md, and lg coordinate section inset, region spacing, and title scale. They do not set width, height, grid columns, or viewport breakpoints.

Examples

Edge media and inset header

tsx
<Card.Root as="article">
  <Image.Root src="/story.jpg">...</Image.Root>
  <Card.Header>
    <Eyebrow>Research</Eyebrow>
    <Card.Title as="h2">A field guide</Card.Title>
    <Card.Description>Practical notes from the team.</Card.Description>
  </Card.Header>
</Card.Root>

The Root clips the media to its outer top corners. Header owns the full text inset below it; do not substitute Content when that top inset is required.

Header action and wrapping footer

tsx
<Card.Root>
  <Card.Header>
    <Card.Title>Workspace</Card.Title>
    <Card.Description>Three active collaborators</Card.Description>
    <Card.Action>
      <Button size="sm" tone="neutral" variant="ghost">Edit</Button>
    </Card.Action>
  </Card.Header>
  <Card.Content>Workspace details</Card.Content>
  <Card.Footer>
    <Button size="sm">Open</Button>
    <Button size="sm" tone="neutral" variant="outline">Archive</Button>
  </Card.Footer>
</Card.Root>

Content-only surface

tsx
<Card.Root variant="subtle">
  <Card.Content>One quiet grouped region.</Card.Content>
</Card.Root>
Public contract

API

Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.

Public exports are Card, CardRootProps, CardRootElement, CardHeaderProps, CardTitleProps, CardTitleElement, CardDescriptionProps, CardActionProps, CardContentProps, CardFooterProps, CardVariant, and CardSize.

Card.Root

PropValuesDefault
asdiv, article, section, lidiv
borderedbooleantrue
variantoutline, elevated, subtleoutline
sizesm, md, lgmd

Root also accepts ordinary HTMLAttributes<HTMLElement>, including id, ARIA and data attributes, events, className, style, and ref. bordered={false} removes only the selected recipe's border geometry while retaining its background, elevation, radius, clipping, and anatomy. It is useful when authored media must reach Card's clipped outer edge.

Card.Title

as accepts h1, h2, h3, h4, h5, or h6 and defaults to h3. Choose the level from the document hierarchy, not the desired visual size. An h1 is valid when Card contains the page's real main title—for example, a sign-in page whose primary content is one Card. Repeated cards normally use h2 or h3.

Other parts

Header, Action, Content, and Footer accept native div attributes. Description accepts native paragraph attributes. All part slots are overridable with data-slot.

Card.Action reserves the Header's trailing grid column across the title and description rows. This is appropriate when both text regions should make room for compact trailing content. When metadata belongs beside only the title and the description should retain the full header measure, compose the title and metadata in a Brick HStack and omit Card.Action.

Shared responsibility

Accessibility

There is no Card ARIA widget. Card adds no role, tab index, accessible name, keyboard handler, focus target, generated ID, or automatic heading relationship.

  • Use article, section, or li only when it matches the document.
  • Label significant articles or sections explicitly when appropriate.
  • Choose the Title level from the page heading structure.
  • Buttons and links inside Card keep their native semantics and focus.
  • Forced-colors mode preserves a visible boundary for every Card variant.
  • Card has no default motion, so reduced motion does not change its meaning.

Responsive behavior

Card is mobile-first and block-sized by its container. It uses minimum-zero columns, logical spacing, long-content wrapping, and a wrapping Footer. Header Action is intended for compact content; put large or multiple actions in Footer.

Application layout remains ordinary CSS:

css
.report-grid {
  display: grid;
  gap: 1rem;
}

@media (min-width: 48rem) {
  .report-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
Stable visual contract

Styling and tokens

Customization

Choose a tested variant and size first:

tsx
<Card.Root size="lg" variant="elevated">...</Card.Root>

Override semantic tokens on an application scope to theme a region. For a local Card adjustment, use the public component tokens:

tsx
<Card.Root
  style={{
    "--brick-card-radius": "0.25rem",
    "--brick-card-space": "2rem",
  } as React.CSSProperties}
>
  ...
</Card.Root>

Customize public anatomy directly rather than using a root class map:

tsx
<Card.Root className="project-card">
  <Card.Header className="project-card__header">...</Card.Header>
  <Card.Content data-slot="project-summary">...</Card.Content>
</Card.Root>

Arbitrary overrides remain the consumer's responsibility for contrast, clipping, focus visibility, and reflow.

Tokens and CSS hooks

Public Card tokens

TokenResponsibility
--brick-card-spaceSection inset and coordinated region spacing
--brick-card-radiusRoot surface radius
--brick-card-border-widthRoot border geometry
--brick-card-shadowElevated surface shadow

Stable classes and slots

PartClassDefault slot
Root.brick-cardcard
Header.brick-card-headercard-header
Title.brick-card-titlecard-title
Description.brick-card-descriptioncard-description
Action.brick-card-actioncard-action
Content.brick-card-contentcard-content
Footer.brick-card-footercard-footer

Root reflects optional data-bordered with the value "false", plus data-variant and data-size. Classes, slots, and the public component tokens are the stable Card-specific CSS contract. Semantic surface, border, text, radius, spacing, and shadow-color tokens remain the normal theme layer.

Advanced reference

Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.

Maintainer resources

Tests, playground evidence, source notes, and release history remain available without crowding the plug-and-play guide.