---
title: "Figure"
description: "Wrap images and media in a figure that keeps to the text column or breaks out to container, screen or card width."
requested_language: nl
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/nl/next/components/figure
version: unreleased (main)
docs_index: https://docs.systhema.app/nl/next/llms.txt
---
> This page isn't translated yet. Showing English.


`Figure` wraps an image, video or embed in a `<figure>` and controls how wide it gets. By default it follows the column it sits in; `width` lets it break out of a narrow column to the container, the whole viewport, or the inner edges of a card.

```tsx preview iframe bleed height=760 title="Figure"
import { Figure, Heading, Image, Paragraph, Section } from '@systhemaui/next'

export default function Demo() {
  return (
    <Section padding={3}>
      <Heading.h2>Ten days on the coast</Heading.h2>
      <Paragraph>
        A figure placed in a section's text column breaks out to the container width, while the text
        around it keeps its comfortable measure.
      </Paragraph>
      <Figure width="container">
        <Image
          src="/demo-assets/coast.webp"
          alt="Waves breaking on a rocky coast"
          width={1800}
          height={1200}
          aspectRatio="21/9"
        />
        <figcaption className="text-small color-label">The northern cliffs at low tide.</figcaption>
      </Figure>
      <Paragraph>The text continues in its column after the figure.</Paragraph>
    </Section>
  )
}
```

## Import

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

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

## Width and breakout behaviour

| `width`     | Class                | Result                                                                                       |
| ----------- | -------------------- | -------------------------------------------------------------------------------------------- |
| `default`   | `figure-w-default`   | Fills the column it sits in. No breakout rule.                                               |
| `container` | `figure-w-container` | Breaks out of any narrower ancestor to `--container-width` (or the viewport, when narrower). |
| `screen`    | `figure-w-screen`    | Breaks out to the full viewport width and never animates in on scroll.                       |
| `card`      | `figure-w-card`      | Breaks out to the inner edges of the surrounding card. Outside a card it has no effect.      |

The breakouts use negative margins (`calc(50% - 50vw)` for `screen`), so the figure's grid cell keeps its place and the content before and after it stays aligned.

## Examples

### Default, container and screen

The three widths inside a section with `padding={3}`. Switch the preview to the phone viewport: below `md` the column has no inset, so `default` and `container` look the same there.

```tsx preview iframe bleed height=1100 title="Widths"
import { Figure, Image, Paragraph, Section } from '@systhemaui/next'

export default function Demo() {
  return (
    <Section padding={3}>
      <Paragraph type="label">width="default"</Paragraph>
      <Figure>
        <Image src="/demo-assets/city.webp" alt="" width={1920} height={1080} aspectRatio="21/9" />
      </Figure>
      <Paragraph type="label">width="container"</Paragraph>
      <Figure width="container">
        <Image
          src="/demo-assets/mountains.webp"
          alt=""
          width={1920}
          height={1080}
          aspectRatio="21/9"
        />
      </Figure>
      <Paragraph type="label">width="screen"</Paragraph>
      <Figure width="screen">
        <Image src="/demo-assets/coast.webp" alt="" width={1800} height={1200} aspectRatio="21/9" />
      </Figure>
    </Section>
  )
}
```

A `screen` figure that is the first or last child of a [`Section`](https://docs.systhema.app/nl/next/components/section.md#full-bleed-media) or an [`Article`](https://docs.systhema.app/nl/next/components/article.md) removes that container's padding on its side, so it sits flush against the edge. `container` figures keep the padding.

### Card width

`width="card"` cancels the card's horizontal padding through the `--card-width-offset-x` variable every card publishes. As the first or last child, the card also drops its own top or bottom padding, so the image meets the card's rounded edge while the text keeps its padding.

```tsx preview iframe height=520 title="Card-width figure"
import { Card, Column, Columns, Figure, Heading, Image, Paragraph } from '@systhemaui/next'

export default function Demo() {
  return (
    <Columns columns={2} gap="md" className="w-full max-w-3xl">
      <Column>
        <Card variant="default">
          <Figure width="card">
            <Image
              src="/demo-assets/dunes-portrait.webp"
              alt=""
              width={1200}
              height={1600}
              aspectRatio="16/10"
            />
          </Figure>
          <Heading.h4>Desert crossing</Heading.h4>
          <Paragraph>The image bleeds to the card's edges.</Paragraph>
        </Card>
      </Column>
      <Column>
        <Card variant="default">
          <Figure>
            <Image
              src="/demo-assets/forest-portrait.webp"
              alt=""
              width={1200}
              height={1600}
              aspectRatio="16/10"
            />
          </Figure>
          <Heading.h4>Forest trail</Heading.h4>
          <Paragraph>The default width keeps the card's padding.</Paragraph>
        </Card>
      </Column>
    </Columns>
  )
}
```

The figure-rendering Payload media blocks (image, video, YouTube, Google Maps and embed) offer the same `card` width when they sit directly inside a card. See [Media inside a card](https://docs.systhema.app/nl/next/payload/blocks/card.md#media-inside-a-card).

### Captions

Put a `<figcaption>` after the media. `Figure` adds no caption styling, so style it with a text utility such as `text-small`.

## Props

`width` defaults to `'default'`. All other props go to the `<figure>` element, including `dangerouslySetInnerHTML`, which renders the figure without children (the embed block converter uses it).

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

| Prop                           | Type                                                     | Default | Description |
| ------------------------------ | -------------------------------------------------------- | ------- | ----------- |
| `children`                     | `ReactNode`                                              | -       |             |
| `width`                        | `'default' \| 'container' \| 'screen' \| 'card' \| null` | -       |             |
| `className`                    | `string`                                                 | -       |             |
| …and all `<figure>` attributes |                                                          |         |             |

<!-- /generated -->

## HTML and CSS

The same figure in plain HTML:

```html
<figure class="figure-w-container">
  <img class="media aspect-21/9 object-cover" src="/images/coast.webp" alt="A rocky coast" />
  <figcaption class="text-small">The northern cliffs at low tide.</figcaption>
</figure>
```

`w-card` is an exact alias of `figure-w-card` for any element. `figure-w-full` is a deprecated alias of `figure-w-screen`, kept for older content; `systhema upgrade` rewrites it in your source. See [Figure width](https://docs.systhema.app/nl/next/styling/figure-width.md).

<!-- generated:utilities figure -->

| Class                | Styles                                                                                                                                                                                                                                                                      |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `figure-w-container` | `width: min(var(--container-width), 100vw);`<br>`max-width: 100vw;`<br>`margin-left: calc((100% - min(var(--container-width), 100vw)) / 2);`<br>`margin-right: calc((100% - min(var(--container-width), 100vw)) / 2);`<br>`margin-block: 0;`                                |
| `figure-w-screen`    | `.py-section:where(:has( > .container > .richtext > .figure-w-screen:first-child,  > .container > .richtext > .figure-w-full:first-child,  > .container > .figure-w-screen:first-child,  > .container > .figure-w-full:first-child)) { padding-top: 0; }`<br>+ 2 more rules |
| `figure-w-full`      | `.py-section:where(:has( > .container > .richtext > .figure-w-screen:first-child,  > .container > .richtext > .figure-w-full:first-child,  > .container > .figure-w-screen:first-child,  > .container > .figure-w-full:first-child)) { padding-top: 0; }`<br>+ 2 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; }`         |

<!-- /generated -->

## Next.js

`@systhemaui/next` re-exports `Figure` from `@systhemaui/react` unchanged. Put the `@systhemaui/next` [`Image`](https://docs.systhema.app/nl/next/components/image.md) or [`Video`](https://docs.systhema.app/nl/next/components/video.md) inside it.

## Accessibility

A `<figcaption>` names the figure for assistive technology, so it can describe the image while `alt` stays short, or the image can take `alt=""` when the caption already says everything. Don't repeat the same text in both.

## Related

- [Image](https://docs.systhema.app/nl/next/components/image.md)
- [Card](https://docs.systhema.app/nl/next/components/card.md)
- [Figure width](https://docs.systhema.app/nl/next/styling/figure-width.md)
- [Section](https://docs.systhema.app/nl/next/components/section.md)
