Card

A filled surface that holds one thing — a place, a person, a plan — and, when its title is a link, opens it from anywhere on the card.

The locations card

  • 164 staff24 services

    Phoenix Clinic Hospital

    Rochester, MN 55905, US

    CST - 8:00am to 10:00pm

  • 98 staff17 services

    Scottsdale Clinic Building

    Scottsdale, AZ 85259, US

    MST - 7:00am to 9:00pm

The drawn card, rebuilt from the five parts. The title is the link and the whole card is where it is pressed; the dots are a menu of their own, over the link.

A surface and five parts

A complex product needs many cards and no list of props survives them. So the Card is the surface and the parts that are hard to get right — the picture set into it, the title that makes the card a link, the controls that stay pressable inside one — and everything else in it is the caller’s.

Staff on shift

164

12 more than last week

Confirmed
A component as the picture

Anything that is not an image is centred on the raised well.

A card with no linked title is a container: it has no hover, no focus ring and no pointer, because it does nothing.

Where it stands

The card is a fill with no border, a step under its ground, as it is drawn: a grey card on a white page. That ground is surface/raised — a section, a panel, a dialog. On the canvas it is one faint step in light and, in dark, nothing: there the sunken surface is the canvas, because the ramp ends and no step is invented below it. A card on the canvas wants a hairline, which is the outline card the site’s own pages use and this package does not have yet.

Where it leaves the drawing

Under the pointer the drawn card turns violet and shows what it was hiding: two counts and a “See details” button. A touch screen and a keyboard have no hover, so nothing is behind it. The counts are information and are always there; the button is gone, since the card is already the link. The hover is the theme’s wash, on the card and on the picture, which rises from elevation/md to lg. The violet is kept for a card that is selected.

The drawn captions are text/tertiary. On this fill they are 4.5:1 or more at rest and 4.27:1 under the wash in light, so the captions of a card that answers the pointer are text/secondary.

Anatomy

Card geometry, in pixels
PartValue
Padding16, a transparent hairline included
Radius16
Between parts8
Picture16 / 9, radius 12, elevation md; lg under the pointer
Body4 block, 8 inline
Title, Semibold16 / 24

Accessibility

The link is the title, so a screen reader hears “Phoenix Clinic Hospital, link” and not the whole card read as one name. The link’s own ::after is stretched over the card, which makes the card the hit area without wrapping it in an a: a menu inside a link would be a control inside a control. CardActions lifts its controls over that area, and whatever is pressable belongs in it: a second link left in the body is under the card’s, and a press on it opens the card. The words of a linked card cannot be selected, which is the price of one link and no nesting. The focus ring is drawn around the card, where :has() is understood, and around the title where it is not. A set of cards is a list: as="li" inside a ul, so their number is said. The title’s level is the page’s to choose.

Using it

TSX
import { Card, CardMedia, CardBody, CardTitle, CardActions } from 'alpenglow';

<ul>
  <Card as="li">
    <CardMedia>
      <img src={location.photo} alt="" />
    </CardMedia>
    <CardBody>
      <CardTitle href={`/locations/${location.id}`}>{location.name}</CardTitle>
      <p>{location.address}</p>
      <CardActions>
        <LocationMenu location={location} />
      </CardActions>
    </CardBody>
  </Card>
</ul>
Card props, by part
PropTypeDefault
Card · as'div' | 'li' | 'article' | 'section''div'
CardMedia · ratioa CSS aspect-ratio, or 'auto''16 / 9'
CardTitle · as'h2' | 'h3' | 'h4' | 'div''h3'
CardTitle · idstring, on the title’s element—
CardTitle · hrefstring—
CardTitle · render(props: LinkRenderProps) => ReactNode, with href—
CardTitle · …anchortarget, rel, onClick and the rest of an anchor’s—
every part · childrenReactNoderequired
every part · classNamestring—