Card
A bordered surface that groups related content. Composes with everything.
A card holds related content as a single unit: an article preview, a feature description, a product tile. Zazz's card is a flexible container with named slots for figure, content, body, and footer. Build whatever the design calls for by composing those parts.
export default function CardBasic() { return ( <a className="card" href="#"> <div className="card__figure"> <img className="card__image" src="https://images.unsplash.com/photo-1500382017468-9049fed747ef?auto=format&fit=crop&w=900&q=60" alt="" /> </div> <div className="card__content"> <div className="card__tags"> <span className="badge badge-link">Field notes</span> </div> <div className="card__body"> <span className="card__title-link"> <h3 className="card__title text-h6">How quickly zebras jump</h3> </span> <p className="card__description text-sm text-muted-foreground line-clamp-2"> Short excerpt that wraps to two lines before truncating. Demonstrates the default card composition. </p> </div> <div className="card__footer"> <div className="avatar-author"> <div className="avatar"> <div className="avatar__initials">DN</div> </div> <div className="avatar-author__info"> <span className="avatar-author__name text-sm">Derek Nelsen</span> <span className="avatar-author__description text-xs text-muted-foreground"> 15 Mar 2025 </span> </div> </div> <span className="card__button button button-muted">Read article</span> </div> </div> </a> );}Anatomy
<a class="card" href="/article">
<a class="card__figure" href="/article">
<img class="card__image" src="/cover.jpg" alt="" />
</a>
<div class="card__content">
<div class="card__tags">
<a class="badge badge-link" href="/category">Category</a>
<a class="badge badge-link" href="/tag">Tag</a>
</div>
<div class="card__body">
<a class="card__title-link" href="/article">
<h3 class="card__title text-h6">How quickly zebras jump</h3>
</a>
<p class="card__description text-sm text-muted-foreground line-clamp-2">
Short excerpt that wraps to two lines before truncating.
</p>
</div>
<div class="card__footer">
<div class="avatar-author">
<div class="avatar"><img class="avatar__profile" src="/author.jpg" alt="" /></div>
<div class="avatar-author__info">
<span class="avatar-author__name text-sm">Author name</span>
<span class="avatar-author__description text-xs text-muted-foreground">15 Mar 2025</span>
</div>
</div>
<a class="card__button button button-muted" href="/article">Read article</a>
</div>
</div>
</a>| Part | Class | Notes |
|---|---|---|
| Root | card | The bordered surface. Width and height stretch to 100% of the container. |
| Figure | card__figure | Optional media region. 3:2 aspect by default, --radius-md corners. Wrap in an anchor for click-through behavior. |
| Image | card__image | Absolute-positioned fill inside card__figure. |
| Content | card__content | Padded text region. Stacks tags, body, and footer with --gap-sm between. |
| Tags | card__tags | Inline badges row with --gap-xs. Often holds badge-link variants. |
| Body | card__body | Title + description stack with --gap-xs. |
| Title | card__title | Heading text. Apply a text style like text-h6 separately. |
| Title link | card__title-link | Anchor wrapping the title for click-through. |
| Description | card__description | Short excerpt. Pair with text-sm, text-muted-foreground, and line-clamp-2. |
| Footer | card__footer | Author meta + CTA row. Wraps when narrow. |
| Footer CTA | card__button | The card's outbound action. Compose with button button-muted or another variant. |
The root can be any clickable element (commonly an <a>) or a plain <div> when the card itself isn't a single click target.
Tokens
| Property | Token / value |
|---|---|
| Width / height | 100% (fills parent) |
| Radius | --radius-card (defaults to --radius-lg) |
| Color | --card-foreground |
| Background | None set on root. Add background: var(--card) if the card needs its own surface. |
| Internal gap | --gap-sm (content, footer), --gap-xs (tags, body) |
| Figure aspect | 3 / 2, --radius-md |
| Title size | Whatever text style you apply (the demo uses text-h6) |
The card root is borderless by default. Combine with border: 1px solid var(--border) and background: var(--card) when the card needs to read as a surface. Without those, the card sits flush with the parent.
Composing
Cards compose with primitives:
- Tags are
badge-linkfor clickable categories. - Author meta uses the Avatar author composition.
- CTA is any Button variant via
card__button.
For a card with an explicit surface and shadow, add a class with background, border, and a box-shadow token at the root.
Accessibility
- Use a single primary clickable element. Either the root
<a>orcard__title-linkshould carry the article's accessible name; nesting both is fine when they point at the same URL. - Image alt should be empty when the title carries the same content (avoids double-announcement).
- Tags inside
card__tagsare independent links and should have their own accessible names.
Cross-platform
| Platform | Reference |
|---|---|
| Figma | Zazz v0.4.4 → card (component with figure, content, body, footer slots) |
| Webflow | card root with card__* child classes |
| CSS / Tailwind | The same classes after installing utilities.css |