# Display

The --display utility and the keywords the kit adds to it: flex directions, the pile, the gallery, and subgrids.

Source: https://www.zazz.sh/api/foundations/display/

`--display` writes the CSS `display` property, so it takes whatever `display` takes: `block`, `flex`, `grid`, `none`, `contents`. The kit adds thirteen keywords of its own. Each sets a display and the thing you would otherwise set right after it: a flex direction, a shared cell, or a set of grid tracks.

| Keyword | What you get |
| --- | --- |
| `flex-row`, `flex-col` | a flex container and its direction |
| `flex-row-reverse`, `flex-col-reverse` | the same, laid out from the far end |
| `inline-flex-row`, `inline-flex-col`, and their `-reverse` forms | an inline flex container and its direction |
| `grid-pile` | a grid with every direct child in one cell, centered |
| `grid-gallery` | a grid that picks its column count from its child count |
| `subgrid` | a grid on its parent grid's columns and rows |
| `subgrid-col` | a grid on its parent grid's columns |
| `subgrid-row` | a grid on its parent grid's rows |

## Breakpoints and spelling

`--display` takes breakpoints and no states. A tier needs a base, so write `--display: none; --display--md: flex` to hide something below `md`; `--display--md: flex` alone does nothing. Every keyword works at every breakpoint: `--display: flex-col; --display--md: grid-gallery` is a stack on a phone and a gallery from `md` up.

The kit matches the keywords as text, so they need exactly [one space after the colon](/api/utilities/#one-space-after-the-colon). `--display:flex-col` is not a flex container. The editor and `<ui-debug>` flag it.

## Flex direction

The direction is part of the display, and there is no `--flex-direction` utility. A plain `flex` or `inline-flex` at a breakpoint goes back to a row.

```html
<div
  style="
    --display: flex-col;
    --gap: 11;
    --w: 100%;
    --max-w: 96;
  "
>
  <div
    style="
      --display: flex-col;
      --gap: 2;
    "
  >
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-muted-foreground);
      "
      >--display: flex-row</span
    >
    <div
      style="
        --display: flex-row;
        --gap: 4;
      "
    >
      <div
        data-ui="text-sm"
        style="
          --flex: 1;
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        1
      </div>
      <div
        data-ui="text-sm"
        style="
          --flex: 1;
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        2
      </div>
      <div
        data-ui="text-sm"
        style="
          --flex: 1;
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        3
      </div>
    </div>
  </div>
  <div
    style="
      --display: flex-col;
      --gap: 2;
    "
  >
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-muted-foreground);
      "
      >--display: flex-col</span
    >
    <div
      style="
        --display: flex-col;
        --gap: 4;
      "
    >
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        1
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        2
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        3
      </div>
    </div>
  </div>
</div>
```

The `-reverse` forms lay the children out from the far end. Only the picture changes. A screen reader and the Tab key still follow the order in the markup, so don't reverse anything a person has to move through in sequence.

```html
<div
  style="
    --display: flex-col;
    --gap: 11;
    --w: 100%;
    --max-w: 96;
  "
>
  <div
    style="
      --display: flex-col;
      --gap: 2;
    "
  >
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-muted-foreground);
      "
    >
      --display: flex-row-reverse
    </span>
    <div
      style="
        --display: flex-row-reverse;
        --gap: 4;
      "
    >
      <div
        data-ui="text-sm"
        style="
          --flex: 1;
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        1
      </div>
      <div
        data-ui="text-sm"
        style="
          --flex: 1;
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        2
      </div>
      <div
        data-ui="text-sm"
        style="
          --flex: 1;
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        3
      </div>
    </div>
  </div>
  <div
    style="
      --display: flex-col;
      --gap: 2;
    "
  >
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-muted-foreground);
      "
    >
      --display: flex-col-reverse
    </span>
    <div
      style="
        --display: flex-col-reverse;
        --gap: 4;
      "
    >
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        1
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        2
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        3
      </div>
    </div>
  </div>
</div>
```

The `inline-flex-` forms sit in a line of text, the way `inline-flex` does.

```html
<div
  style="
    --display: flex-col;
    --gap: 6;
    --w: 100%;
    --max-w: 96;
  "
>
  <p data-ui="text-sm" style="--m: 0">
    An <code>inline-flex-row</code> box sits in the line
    <span
      style="
        --display: inline-flex-row;
        --px: 2;
        --py: 1;
        --gap: 1;
        --text: var(--color-primary-foreground);
        --bg: var(--color-primary);
        --radius: 2.5;
      "
    >
      <b>one</b>
      <b>two</b>
    </span>
    and the sentence carries on.
  </p>
  <p data-ui="text-sm" style="--m: 0">
    An <code>inline-flex-col</code> box stacks its children
    <span
      style="
        --display: inline-flex-col;
        --px: 2;
        --py: 1;
        --gap: 1;
        --text: var(--color-muted-foreground);
        --bg: var(--color-muted);
        --radius: 2.5;
      "
    >
      <b>one</b>
      <b>two</b>
    </span>
    and the sentence carries on.
  </p>
</div>
```

For wrapping, growing, and alignment, see [flexbox and grid](/api/utilities/flexbox-grid/).

## Pile

`--display: grid-pile` puts every direct child in the same grid cell and centers it. It does what `position: absolute` layering does, except that the children stay in flow and the tallest one sets the height.

```html
<div
  style="
    --display: grid-pile;
    --w: 100%;
    --h: 6;
    --max-w: 96;
  "
>
  <div
    style="
      --size: 100%;
      --bg: var(--color-muted);
      --radius: 4.5;
    "
  ></div>
  <span data-ui="badge" data-badge-variant="primary">grid-pile</span>
  <span
    data-ui="badge"
    data-badge-variant="muted"
    style="
      --self: start;
      --mt: 4;
      --ml: auto;
      --mr: 4;
    "
    >stacked layer</span
  >
</div>
```

The centering beats a primitive's own alignment. A child's own placement wins over it, and so do `--place-items` and `--items` on the pile. On a layered hero, add `--isolation: isolate` so the layers' `--z` values stay inside it.

## Gallery

`--display: grid-gallery` works out its own column count. It puts as many children in a row as fit, up to six, and it won't pick a count that leaves one child alone in the last row. Six children go 6, then 4 + 2, then 3 + 3 as the space narrows. They never go 5 + 1.

```html
<div
  style="
    --display: flex-col;
    --gap: 11;
    --w: 100%;
    --max-w: 160;
  "
>
  <div
    style="
      --display: flex-col;
      --gap: 2;
    "
  >
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-muted-foreground);
      "
    >
      4 children: one row of four, or 2 + 2
    </span>
    <div
      style="
        --display: grid-gallery;
        --gap: 2;
        --ui-gallery-min-w: 5rem;
      "
    >
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        1
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        2
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        3
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        4
      </div>
    </div>
  </div>
  <div
    style="
      --display: flex-col;
      --gap: 2;
    "
  >
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-muted-foreground);
      "
    >
      5 children: one row of five, or 3 + 2
    </span>
    <div
      style="
        --display: grid-gallery;
        --gap: 2;
        --ui-gallery-min-w: 5rem;
      "
    >
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        1
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        2
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        3
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        4
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-muted-foreground);
          --bg: var(--color-muted);
          --radius: 2.5;
        "
      >
        5
      </div>
    </div>
  </div>
  <div
    style="
      --display: flex-col;
      --gap: 2;
    "
  >
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-muted-foreground);
      "
    >
      7 children: 5 + 2, or 4 + 3
    </span>
    <div
      style="
        --display: grid-gallery;
        --gap: 2;
        --ui-gallery-min-w: 5rem;
      "
    >
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        1
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        2
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        3
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        4
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        5
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        6
      </div>
      <div
        data-ui="text-sm"
        style="
          --p: 4;
          --font-weight: strong;
          --text-align: center;
          --text: var(--color-primary-foreground);
          --bg: var(--color-primary);
          --radius: 2.5;
        "
      >
        7
      </div>
    </div>
  </div>
</div>
```

A child is at least `--ui-gallery-min-w` wide, `20ch` by default. Set it on the gallery to change how soon the columns drop: `--ui-gallery-min-w: 12rem` suits cards, and something like `5rem` suits logos.

It can't always avoid a lone child:

- At two columns an odd count still ends on one. The only alternative is a single column, which is worse.
- 13, 21, 25, and 31 children end on one at some widths, because the next count down leaves one alone too.

A few things to know before you rely on it:

- It counts the children that take a cell. Children with `hidden`, and `<template>`, `<script>`, and `<style>`, are left out.
- It reads the gap from `--gap` or `--gap-x`. It can't see a gap set in a stylesheet or by a primitive, and near a width where the count changes that can let a lone child through.
- A child that spans columns with `--col-span` is still counted once, so keep each child to one cell.
- A `--grid-cols` on the gallery at the same breakpoint is ignored. At a higher one it takes over: `--display: grid-gallery; --grid-cols--lg: 4` is a gallery up to `lg` and four columns after.

## Subgrid

A subgrid is a grid item that lays its own children out on its parent grid's tracks. It needs to be a direct child of a grid, and it needs to span the tracks it wants with `--col-span` or `--row-span`.

`--display: subgrid-col` takes the parent's columns, so a nested row lines up with the cells above it:

```html
<div
  style="
    --display: grid;
    --template-cols: 1fr 2fr 1fr 1fr;
    --gap: 2;
    --w: 100%;
    --max-w: 120;
  "
>
  <div
    data-ui="text-sm"
    style="
      --p: 4;
      --font-weight: strong;
      --text-align: center;
      --text: var(--color-primary-foreground);
      --bg: var(--color-primary);
      --radius: 2.5;
    "
  >
    1
  </div>
  <div
    data-ui="text-sm"
    style="
      --p: 4;
      --font-weight: strong;
      --text-align: center;
      --text: var(--color-primary-foreground);
      --bg: var(--color-primary);
      --radius: 2.5;
    "
  >
    2
  </div>
  <div
    data-ui="text-sm"
    style="
      --p: 4;
      --font-weight: strong;
      --text-align: center;
      --text: var(--color-primary-foreground);
      --bg: var(--color-primary);
      --radius: 2.5;
    "
  >
    3
  </div>
  <div
    data-ui="text-sm"
    style="
      --p: 4;
      --font-weight: strong;
      --text-align: center;
      --text: var(--color-primary-foreground);
      --bg: var(--color-primary);
      --radius: 2.5;
    "
  >
    4
  </div>
  <div
    style="
      --display: subgrid-col;
      --col-span: 4;
    "
  >
    <div
      data-ui="text-sm"
      style="
        --p: 4;
        --font-weight: strong;
        --text-align: center;
        --text: var(--color-muted-foreground);
        --bg: var(--color-muted);
        --radius: 2.5;
      "
    >
      a
    </div>
    <div
      data-ui="text-sm"
      style="
        --p: 4;
        --font-weight: strong;
        --text-align: center;
        --text: var(--color-muted-foreground);
        --bg: var(--color-muted);
        --radius: 2.5;
      "
    >
      b
    </div>
    <div
      data-ui="text-sm"
      style="
        --col-span: 2;
        --p: 4;
        --font-weight: strong;
        --text-align: center;
        --text: var(--color-muted-foreground);
        --bg: var(--color-muted);
        --radius: 2.5;
      "
    >
      c + d
    </div>
  </div>
</div>
```

`--display: subgrid-row` takes the parent's rows. Give each card three rows and the titles, text, and footers stay level, however long one of them runs:

```html
<div
  style="
    --display: grid;
    --grid-cols: 3;
    --gap-x: 4;
    --gap-y: 2;
    --w: 100%;
    --max-w: 160;
  "
>
  <article
    style="
      --display: subgrid-row;
      --row-span: 3;
      --p: 4;
      --bg: var(--color-muted);
      --radius: 2.5;
    "
  >
    <strong data-ui="text-sm"> Warbler </strong>
    <p
      data-ui="text-sm"
      style="
        --m: 0;
        --text: var(--color-muted-foreground);
      "
    >
      Seen once, at dawn.
    </p>
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-primary);
      "
    >
      Rare
    </span>
  </article>
  <article
    style="
      --display: subgrid-row;
      --row-span: 3;
      --p: 4;
      --bg: var(--color-muted);
      --radius: 2.5;
    "
  >
    <strong data-ui="text-sm"> Great blue heron on the east pond </strong>
    <p
      data-ui="text-sm"
      style="
        --m: 0;
        --text: var(--color-muted-foreground);
      "
    >
      A resident pair nests in the dead oak every spring and fishes the shallows through October.
    </p>
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-primary);
      "
    >
      Common
    </span>
  </article>
  <article
    style="
      --display: subgrid-row;
      --row-span: 3;
      --p: 4;
      --bg: var(--color-muted);
      --radius: 2.5;
    "
  >
    <strong data-ui="text-sm"> Kestrel </strong>
    <p
      data-ui="text-sm"
      style="
        --m: 0;
        --text: var(--color-muted-foreground);
      "
    >
      Hovers over the meadow most afternoons.
    </p>
    <span
      data-ui="text-xs"
      style="
        --font-weight: strong;
        --text: var(--color-primary);
      "
    >
      Seasonal
    </span>
  </article>
</div>
```

`--display: subgrid` takes both, and the children land on the parent's cells:

```html
<div
  style="
    --display: grid;
    --template-cols: 1fr 2fr 1fr;
    --gap: 2;
    --w: 100%;
    --max-w: 120;
  "
>
  <div
    data-ui="text-sm"
    style="
      --p: 4;
      --font-weight: strong;
      --text-align: center;
      --text: var(--color-primary-foreground);
      --bg: var(--color-primary);
      --radius: 2.5;
    "
  >
    1
  </div>
  <div
    data-ui="text-sm"
    style="
      --p: 4;
      --font-weight: strong;
      --text-align: center;
      --text: var(--color-primary-foreground);
      --bg: var(--color-primary);
      --radius: 2.5;
    "
  >
    2
  </div>
  <div
    data-ui="text-sm"
    style="
      --p: 4;
      --font-weight: strong;
      --text-align: center;
      --text: var(--color-primary-foreground);
      --bg: var(--color-primary);
      --radius: 2.5;
    "
  >
    3
  </div>
  <div
    data-ui="text-sm"
    style="
      --p: 4;
      --font-weight: strong;
      --text-align: center;
      --text: var(--color-primary-foreground);
      --bg: var(--color-primary);
      --radius: 2.5;
    "
  >
    4
  </div>
  <div
    style="
      --display: subgrid;
      --col-span: 2;
      --row-span: 2;
    "
  >
    <div
      data-ui="text-sm"
      style="
        --p: 4;
        --font-weight: strong;
        --text-align: center;
        --text: var(--color-muted-foreground);
        --bg: var(--color-muted);
        --radius: 2.5;
      "
    >
      a
    </div>
    <div
      data-ui="text-sm"
      style="
        --p: 4;
        --font-weight: strong;
        --text-align: center;
        --text: var(--color-muted-foreground);
        --bg: var(--color-muted);
        --radius: 2.5;
      "
    >
      b
    </div>
    <div
      data-ui="text-sm"
      style="
        --p: 4;
        --font-weight: strong;
        --text-align: center;
        --text: var(--color-muted-foreground);
        --bg: var(--color-muted);
        --radius: 2.5;
      "
    >
      c
    </div>
    <div
      data-ui="text-sm"
      style="
        --p: 4;
        --font-weight: strong;
        --text-align: center;
        --text: var(--color-muted-foreground);
        --bg: var(--color-muted);
        --radius: 2.5;
      "
    >
      d
    </div>
  </div>
  <div
    data-ui="text-sm"
    style="
      --p: 4;
      --font-weight: strong;
      --text-align: center;
      --text: var(--color-primary-foreground);
      --bg: var(--color-primary);
      --radius: 2.5;
    "
  >
    5
  </div>
</div>
```

If the number of children varies, use `subgrid-col` or `subgrid-row`. A two-axis subgrid has no spare tracks for the extra ones.

The axis a subgrid does not take keeps its own `--grid-cols` or `--grid-rows`. Across breakpoints, the highest one that names a display or a count decides:

- `--display: grid; --grid-cols: 2; --display--md: subgrid-col` is two columns below `md` and the parent's columns from there up.
- `--display: subgrid-col; --grid-cols--lg: 3` is the parent's columns up to `lg` and three columns after.
- At the same breakpoint the display wins, so `--display: subgrid-col; --grid-cols: 3` ignores the count.

`--grid-cols: subgrid` and `--grid-rows: subgrid` no longer exist. The editor and `vp run lint:html` suggest the rewrite. `--template-cols: subgrid` and `--template-rows: subgrid` still work, for an element whose display you can't change.

## Plain grid

`--display: grid` and `inline-grid` pack their rows at the top instead of stretching them, and `--place-content` changes that. The [flexbox and grid](/api/utilities/flexbox-grid/) page has the details, along with tracks, placement, and gaps.
