---
title: "Card"
description: "Token-variant cards as a div or a whole-card link, with theme and card-width figures."
requested_language: fr
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/fr/components/card
version: unreleased (main)
docs_index: https://docs.systhema.app/fr/llms.txt
---
> This page isn't translated yet. Showing English.


A card is a padded, bordered box whose look comes from a card variant in your tokens. Use it for teasers, feature lists and pricing tiles, either as a plain container or as one large link.

```tsx preview title="Card"
import { Button, Card, Heading, Paragraph } from '@systhemaui/next'

export default function Demo() {
  return (
    <Card style={{ maxWidth: 360 }}>
      <Heading.h3>Design tokens</Heading.h3>
      <Paragraph>
        Colors, spacing and type come from one Figma export, so every card on the site stays in sync
        with the design.
      </Paragraph>
      <Button.a href="#examples" variant="secondary">
        Read more
      </Button.a>
    </Card>
  )
}
```

## Import

```tsx
import { Card } from '@systhemaui/next'
```

In a React app without Next.js, import it from `@systhemaui/react`.

## Variants and tags

`variant` takes a card variant from your tokens: `default` and `highlighted` with the default tokens. Omit it to get the first variant. Each token variant becomes one class, `card-<variant>`, with its own padding, border, radius, shadow and colors.

```tsx preview title="Card variants"
import { Card, Column, Columns, Heading, Paragraph } from '@systhemaui/next'

export default function Demo() {
  return (
    <Columns columns={2} gap="md" style={{ width: '100%' }}>
      <Column>
        <Card variant="default">
          <Heading.h4>Default</Heading.h4>
          <Paragraph>The everyday card for lists and teasers.</Paragraph>
        </Card>
      </Column>
      <Column>
        <Card variant="highlighted">
          <Heading.h4>Highlighted</Heading.h4>
          <Paragraph>Draws the eye to one item in a group.</Paragraph>
        </Card>
      </Column>
    </Columns>
  )
}
```

The tag variants pick the element:

| Tag variant | Renders                                                               |
| ----------- | --------------------------------------------------------------------- |
| `Card`      | `<div>`, or the element you pass as `as`                              |
| `Card.div`  | `<div>`                                                               |
| `Card.a`    | a link (in `@systhemaui/next`, a `next/link`; see [Next.js](#nextjs)) |
| `Card.link` | `@systhemaui/next` only: the same `next/link` card as `Card.a`        |

## Examples

### Theme

`theme` sets `data-theme` on the card, so it renders in another color-system mode than the page around it. With the default tokens the modes are `default` and `dark`. See [Themes and backgrounds](https://docs.systhema.app/fr/concepts/themes.md#the-theme-prop).

```tsx preview title="Dark card on a light page"
import { Card, Heading, Paragraph } from '@systhemaui/next'

export default function Demo() {
  return (
    <Card theme="dark" style={{ maxWidth: 360 }}>
      <Heading.h4>Night shift</Heading.h4>
      <Paragraph>
        The card switches to the dark mode of the color system; its text and border tokens follow.
      </Paragraph>
    </Card>
  )
}
```

### Linked cards

Use `Card.a` (or `Card.link`) when the whole card is the link, instead of wrapping a card in a separate link. A linked card gets the variant's hover colors and your `transitionClasses`.

```tsx preview title="Whole-card links"
import { Card, Column, Columns, Heading, Paragraph } from '@systhemaui/next'

export default function Demo() {
  return (
    <Columns columns={2} gap="md" style={{ width: '100%' }}>
      <Column>
        <Card.a href="#linked-cards">
          <Heading.h4>Getting started</Heading.h4>
          <Paragraph>Install the packages and render your first page.</Paragraph>
        </Card.a>
      </Column>
      <Column>
        <Card.a href="#linked-cards" variant="highlighted">
          <Heading.h4>Components</Heading.h4>
          <Paragraph>Browse every component with live examples.</Paragraph>
        </Card.a>
      </Column>
    </Columns>
  )
}
```

Keep the content of a linked card free of other links and buttons: interactive elements nested in a link are invalid HTML and confuse keyboard and screen-reader users.

### Card-width figures

A [`Figure`](https://docs.systhema.app/fr/components/figure.md#card-width) with `width="card"` breaks out of the card's horizontal padding to its edges. As the first or last child it also drops the card's top or bottom padding, so media sits flush against the rounded corners.

```tsx preview title="Figure flush to the card edges"
import { Card, Figure, Heading, Image, Paragraph } from '@systhemaui/next'

export default function Demo() {
  return (
    <Card style={{ maxWidth: 360 }}>
      <Figure width="card">
        <Image
          src="/demo-assets/coast.webp"
          alt="A coastline at dusk"
          width={1800}
          height={1200}
          sizes="360px"
        />
      </Figure>
      <Heading.h4>Edge to edge</Heading.h4>
      <Paragraph>The figure ignores the card padding; the text keeps it.</Paragraph>
    </Card>
  )
}
```

### Rich text inside a card

A card carries the `richtext` class, so headings, paragraphs, lists and buttons inside it get the [rich-text rhythm](https://docs.systhema.app/fr/concepts/spacing-model.md) without extra margins. The card animates as one unit: animated elements inside it render in their end state without a reveal of their own. Pass `disableAnimation` to drop the card's own reveal as well.

## Props

`Card` and `Card.div` accept `as`, `variant`, `theme`, `disableAnimation` and every attribute of the rendered element.

<!-- generated:props @systhemaui/react CardProps -->

| Prop                        | Type                                     | Default | Description |
| --------------------------- | ---------------------------------------- | ------- | ----------- |
| `as`                        | `ElementType`                            | `'div'` |             |
| `className`                 | `string`                                 | -       |             |
| `variant`                   | `CardVariant` (`default`, `highlighted`) | -       |             |
| `theme`                     | `ColorSystem` (`dark`, `default`)        | -       |             |
| `disableAnimation`          | `boolean`                                | -       |             |
| …and all `<div>` attributes |                                          |         |             |

<!-- /generated -->

## HTML and CSS

Write the variant class plus `richtext` on any element. The variant classes are generated per token variant (`card-default` and `card-highlighted` with the default tokens), and their values come from the `card` tokens in [spacing](https://docs.systhema.app/fr/reference/tokens/spacing.md#card) and [colors](https://docs.systhema.app/fr/reference/tokens/colors.md#card).

```html
<div class="card-highlighted richtext">
  <h3 class="text-h3 color-heading">Design tokens</h3>
  <p class="text-body color-body">Colors, spacing and type come from one Figma export.</p>
</div>

<a class="card-default richtext" href="/getting-started">
  <h3 class="text-h3 color-heading">Getting started</h3>
  <p class="text-body color-body">Install the packages and render your first page.</p>
</a>

<div class="card-default richtext" data-theme="dark">…</div>
```

<!-- generated:utilities card -->

| Class              | Styles                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `card-default`     | `:is(.richtext > :is(.columns, .stack, :is(.card-default), .card-highlighted, .accordion-default)):not(:first-child) { margin-top: calc(var(--typography-block-margin-y, 24px) * 2); }`<br>`:is(.richtext > :is(.columns, .stack, :is(.card-default), .card-highlighted, .accordion-default)):not(:last-child) { margin-bottom: calc(var(--typography-block-margin-y, 24px) * 2); }`<br>+ 9 more rules |
| `figure-w-card`    | `& { width: calc(100% + var(--card-width-offset-x, 0px) * 2); max-width: calc(100% + var(--card-width-offset-x, 0px) * 2); margin-inline: calc(var(--card-width-offset-x, 0px) * -1); border-radius: 0; }`<br>`& :is(.media, .media-wrapper) { border-radius: 0; }`                                                                                                                                    |
| `w-card`           | `& { width: calc(100% + var(--card-width-offset-x, 0px) * 2); max-width: calc(100% + var(--card-width-offset-x, 0px) * 2); margin-inline: calc(var(--card-width-offset-x, 0px) * -1); border-radius: 0; }`<br>`& :is(.media, .media-wrapper) { border-radius: 0; }`                                                                                                                                    |
| `card-highlighted` | `:is(.richtext > :is(.columns, .stack, .card-default, :is(.card-highlighted), .accordion-default)):not(:first-child) { margin-top: calc(var(--typography-block-margin-y, 24px) * 2); }`<br>`:is(.richtext > :is(.columns, .stack, .card-default, :is(.card-highlighted), .accordion-default)):not(:last-child) { margin-bottom: calc(var(--typography-block-margin-y, 24px) * 2); }`<br>+ 9 more rules |

<!-- /generated -->

## Next.js

The `@systhemaui/next` card is its own implementation. `Card.a` and `Card.link` render through the [`LinkHelper`](https://docs.systhema.app/fr/components/utilities.md#linkhelper), so the link is a `next/link` (with prefetching) and same-page hash links smooth-scroll. Passing `as="a"` takes the same route instead of rendering a bare `<a>`. `Card.link` is an alias that names the `next/link` rendering; it does not exist in `@systhemaui/react`, where `Card.a` is a plain anchor.

<!-- generated:props @systhemaui/next CardLinkProps -->

| Prop                                           | Type                                     | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ---------------------------------------------- | ---------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `as`                                           | `ElementType`                            | -       | Optional decorator for the path that will be shown in the browser URL bar. Before Next.js 9.5.3 this was used for dynamic routes, check our [previous docs](https://github.com/vercel/next.js/blob/v9.5.2/docs/api-reference/next/link.md#dynamic-routes) to see how it worked. Note: when this path differs from the one provided in `href` the previous `href`/`as` behavior is used as shown in the [previous docs](https://github.com/vercel/next.js/blob/v9.5.2/docs/api-reference/next/link.md#dynamic-routes). |
| `className`                                    | `string`                                 | -       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `variant`                                      | `CardVariant` (`default`, `highlighted`) | -       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `theme`                                        | `ColorSystem` (`dark`, `default`)        | -       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `disableAnimation`                             | `boolean`                                | -       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `rel`                                          | `string`                                 | -       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `children`                                     | `ReactNode`                              | -       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `target`                                       | `string`                                 | -       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| …and all `InternalLinkProps` props from `next` |                                          |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| …and all inherited HTML attributes             |                                          |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |

<!-- /generated -->

## Accessibility

- A card is a generic container with no role. Give it a heading so its content can be found by heading navigation.
- The accessible name of a linked card is all of its text. Keep that text short, and do not nest buttons or other links inside it.
- A linked card has no visible focus style of its own beyond the browser outline. Keep the outline, or add a `focus-visible:` utility.

## Related

- [Card block](https://docs.systhema.app/fr/payload/blocks/card.md)
- [Figure](https://docs.systhema.app/fr/components/figure.md)
- [Columns](https://docs.systhema.app/fr/components/columns.md) and [Stack](https://docs.systhema.app/fr/components/stack.md) for card grids
- [Themes and backgrounds](https://docs.systhema.app/fr/concepts/themes.md)
