Card

A rounded surface that groups content about one subject.

StableSince 1.0.0
On this page

Import

import { Card } from '@envsemble/envui';

Usage

A content card takes its title, a meta fact at the end of the title row, a description under it, its content as children, and actions in a strip along the bottom.

  • Set render={<article />} on a card that stands on its own.
ActionStrip.tsx
import { Button, Card, Text } from '@envsemble/envui';

export default function ActionStrip() {
  return (
    <Card
      render={<article />}
      title="Pricing research"
      meta="Updated yesterday"
      actions={
        <>
          <Button variant="outline">Share</Button>
          <Button>Open project</Button>
        </>
      }
      style={{ inlineSize: 'min(100%, 28rem)' }}
    >
      <Text emphasis="muted">Interviews and survey results from twelve teams.</Text>
    </Card>
  );
}

With href, the whole card is one native link, through the application's router link from LinkProvider; with onClick, it is one native button.

  • Either holds only phrasing content, such as spans, and no links or controls of its own, and its text names it.
  • disabled turns either off.
<Card href="/projects/northwind">
  <Text render={<span />} variant="title">
    Northwind launch
  </Text>
  <Text render={<span />} emphasis="muted">
    12 open tasks
  </Text>
</Card>

Feature card

A feature card is a Card holding a Row with wrap and align="center": the icon in a muted Text with render={<span />}, a Column of a headline Text and a body-sm Text, and the Button that starts the feature.

  • The Column takes flex: '1 1 16rem', so the text keeps at least 16 rem and the button wraps below it in a narrower card.
  • Render the heading at the level the outline needs, such as render={<h3 />} under a section's h2; variant="headline" keeps its look.
  • The Button takes href where the action goes somewhere.
  • Lay several side by side in a Grid of even columns.
<Card>
  <Row wrap align="center" gap={4}>
    <Text render={<span />} emphasis="muted">
      <IconUploadFile width="1.5rem" height="1.5rem" />
    </Text>
    <Column gap={1} style={{ flex: '1 1 16rem' }}>
      <Text render={<h3 />} variant="headline">
        Import your plans
      </Text>
      <Text variant="body-sm">Bring in spreadsheets and documents from another tool.</Text>
    </Column>
    <Button variant="secondary">Import</Button>
  </Row>
</Card>

Backgrounds

background is muted, the default, default or page. default names the token role it paints, --env-color-bg-default, as Surface's does, not Card's default.

<Card background="default" title="Notifications">
  <Text emphasis="muted">Email for mentions and a weekly summary.</Text>
</Card>

Loading

skeleton shows the card as its own skeleton until its content arrives: text becomes bars and controls filled shapes.

  • Render the same cards over placeholder items, from placeholders.
  • A title or description given as undefined is a bar of its usual length.
<Grid columns={2} gap={4}>
  {(members ?? placeholders<Member>(2)).map((member) => (
    <Card key={member.id} skeleton={!members} title={member.name} description={member.role} />
  ))}
</Grid>

Composition

The title is an h3; set headingLevel to fit the page's outline, and its type stays the title type.

  • Lay out the content with Text, Row and Column, one card per subject, never a card inside a card, and put cards side by side in a Grid.
  • A card fills its container's width.
  • The parts are the surface, env-card, its header, env-card-header, with the title, env-card-title, and the meta, env-card-meta; the description, env-card-description; the body, env-card-body; and the actions, env-card-footer.
  • A feature card's parts are envUI's own components inside it: its icon, env-card env-text > svg, its heading, env-card env-text[data-variant='headline'], its sentence, env-card env-text[data-variant='body-sm'], and its action, env-card env-button.

Customize

  • Its hover, focus and press then follow them, as state layers; with none set, it keeps its own colors.
  • padding sets the inset as a step of the spacing scale, such as 6 for 2 rem, and 0 removes it.

Accessibility

You provide

  • A headingLevel that fits the page's outline.
  • render={<article />} for a card that stands on its own.
  • No aria-label that leaves out the card's visible text.
  • Routing behind href, through LinkProvider.

envUI provides

  • Native <a> and <button> for link and button cards, named by their text.
  • The title as an h3, or the level of headingLevel.
  • A focus outline, and aria-disabled on a disabled link card.

Props

Card

A rounded surface that groups content about one subject: a content card with an optional title row and actions, or one link or button.

PropTypeDescription
backgroundDefault 'muted'
'muted''default''page'
The fill: muted, the standalone card fill; default, a quieter fill that groups content, such as a section of a settings page; or page, the page's own color, for a card inside a pane.
paddingDefault 1.25 rem in narrow windows, growing to 1.5 rem from 50 rem wide
0123456789
The inset on every side, as a step of the spacing scale, such as 6 for 2 rem; 0 removes it. Without it, the inset follows the window's width.
className
string
The card's class, beside env-card.
style
CSSProperties
Styles of the card.
skeletonDefault false
boolean
Shows it and its content as a busy skeleton while that loads; turning it on or off renders the content anew.
title
ReactNode
The card's title at the top: an `h3` in the title type. headingLevel sets another level. Given as undefined, such as over a placeholder item, a skeleton shows a bar in its place.
headingLevelDefault 3
123456
The title's heading level, for the page's outline; the type stays the title type.
meta
ReactNode
A short fact at the end of the title row, such as when the card was updated.
description
ReactNode
A sentence under the title, in muted text.
actions
ReactNode
The card's controls, such as Buttons, in a strip along the bottom of the card.
render
ReactElement
The element for the card's meaning, such as render={<article />} or render={<section />}. A div by default.
href
string
The destination: the whole card is one native link, through the LinkProvider.
onClick
MouseEventHandler<HTMLButtonElement>
Required in some forms. Runs when the card is pressed: the whole card is one native button.
disabledDefault false
boolean
A disabled link card has no destination, cannot be focused and reports aria-disabled; a disabled button card cannot be pressed.

Also accepts the native props of <div>, <a> or <button>, such as ref, className and aria-* attributes.

Part names

Each part's class and state attributes are public and versioned, for an application's CSS to style.

env-card
The card's surface.
env-card-body
The card's content above the footer.
env-card-description
The sentence under the title.
env-card-footer
The strip of actions.
env-card-header
The row with the title and the meta.
env-card-meta
The short fact at the end of the title row.
env-card-title
The title.
data-actions
Present
data-background
page
data-env-skeleton
Any value, or present on env-card, env-card-description, env-card-header, env-card-meta, env-card-title
data-interactive
Present

Color properties

Each sets a color of one instance, through style or CSS; its hover, focus and press follow it. They are public and versioned.

--env-card-container
The card's surface; an interactive card's state layers lie over it.
--env-card-content
The text, and the color of an interactive card’s state layers.
--env-card-outline
An edge in this color.

Changelog

1.0.0

ClickableCard, ActionCard and FeatureCard are Card: onClick makes a button card, render the element of a content card, and the feature card is a Card holding a Row of Text and a Button, as Feature card shows, in place of layout and icon, with env-card-layout and env-card-icon. tone is background, heading is title, which takes headingLevel, and Card takes description; the native title attribute is not a prop of a card. The page is card, after the component.

1.0.0-prerelease.6

Colors under the pointer and while pressed change with --env-motion-ease-enter, rather than easing in slowly, so hover and press show from the first frame.

A page card's action strip takes no band of its own, so the card no longer shows as its strip alone.

1.0.0-prerelease.3

The feature cards pattern is the feature card on this page, which the pattern's address opens.