> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Grid - Web

> Create CSS Grid containers.

> [!NOTE]
>
> For development, import `Grid` from
> `@servicetitan/anvil2`. For design, find it in the
> [Anvil2 file](https://www.figma.com/design/xaNQsvRKczoxu7pj0M6QT8/Anvil2-v3).

**Implementation**

grid-playground

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/grid-playground?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Grid, Card } from "@servicetitan/anvil2";

function App() {
  return (
    <Grid
      templateColumns="repeat(5, 1fr)"
      autoRows="minmax(3rem, auto)"
      rowGap="2"
      columnGap="4"
    >
      <Card background="stronger" gridColumn="1 / 6">
        1
      </Card>
      <Card background="stronger" gridColumn={1} gridRow="2 / 5">
        2
      </Card>
      <Card background="strong" gridColumn="2 / 5" gridRowStart={2}>
        3
      </Card>
      <Card background="stronger" gridColumn="5 / 6" gridRowStart={2}>
        4
      </Card>
      <Card background="strong" gridColumn="2 / 6" gridRow="3 / 5">
        5
      </Card>
    </Grid>
  );
}

export default App;
```

## Common Examples

```tsx theme={null}
import { Grid } from "@servicetitan/anvil2";

const ExampleComponent = () => (
  <Grid templateColumns="repeat(3, 1fr)" gap="2">
    <Grid.Item>First</Grid.Item>
    <Grid.Item gridColumn="span 2">Spans two columns</Grid.Item>
  </Grid>
);
```

### Creating CSS Grid layouts

The `Grid` component renders a `div` with `display: grid`. Set `inline` to render `display: inline-grid` instead. Track sizing, placement, alignment, and spacing are props. Each prop is written as an inline style and maps to a CSS property.

`Grid.Item` renders the cell: a `div` that accepts placement props such as `gridColumn`, `gridRow`, and `alignSelf`. Any child can sit in the grid. Use `Grid.Item` when the cell needs those props and is not already a component that accepts layout utilities. The playground puts `gridColumn` and `gridRow` on `Card` because `Card` accepts those props directly.

A `Grid` is always a grid container. Nested inside another `Grid`, it is also a grid item, and the placement props apply to that outer grid. Nested inside [Flex](https://anvil.servicetitan.com/docs/components/flex/web.md), it is a flex item, and the flex item props apply.

Layout props are merged after `style`, so they override the same CSS property set on `style`. `className` is combined with the component class.

### Responsive props

`sm`, `md`, `lg`, `xl`, and `xxl` override props from that viewport width up. Widths come from the Hammer breakpoints:

| Prop | Applies at |
| - | - |
| `sm` | `640px` and wider |
| `md` | `768px` and wider |
| `lg` | `1024px` and wider |
| `xl` | `1280px` and wider |
| `xxl` | `1536px` and wider |

Base props apply at every width, including below `640px`. There is no `xs` prop. Each property resolves on its own: the largest matching breakpoint that sets it wins, and otherwise the base value is used.

A breakpoint object accepts the container, placement, and flex props. It does not accept `inline`. Nested `sm`, `md`, `lg`, `xl`, or `xxl` keys inside a breakpoint object are ignored.

The example below is one column by default and two columns from `md` up.

grid-responsive

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/grid-responsive?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Grid } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ width: "calc(100vw - 4rem)" }}>
      <Grid
        templateColumns="repeat(1, 1fr)"
        md={{ templateColumns: "repeat(2, 1fr)" }}
        gap="2"
      >
        <div style={{ backgroundColor: "red", height: 20 }} />
        <div style={{ backgroundColor: "green", height: 20 }} />
        <div style={{ backgroundColor: "blue", height: 20 }} />
        <div style={{ backgroundColor: "black", height: 20 }} />
      </Grid>
    </div>
  );
}

export default App;
```

## Best Practices

* Use [Layout](https://anvil.servicetitan.com/docs/components/layout/web.md) for the column structure of a page.
* Use `Grid` for [CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) regions inside that content.
* Use `Grid.Item` for a cell that needs placement props. Pass those props to `Card` (or another layout-aware component) when that component is the cell.
* The playground uses `Card` only to visualize areas. See [Card usage guidelines](https://anvil.servicetitan.com/docs/components/card/web.md#usage-guidelines).

## React Accessibility

`Grid` and `Grid.Item` render `div` elements. They do not set a role, and they do not handle keyboard interaction. Put focusable controls in the cell content. A generic `div` does not receive an accessible name from `aria-label` or `aria-labelledby` alone. To name the region, set a role that supports an accessible name, such as `role="region"`, together with `aria-label` or `aria-labelledby`.

`gridColumn`, `gridRow`, and `order` change visual position only. Assistive technology follows DOM order. Keep the source order in the reading sequence you want announced.

**Grid Props**

```tsx theme={null}
<Grid
  alignContent="stretch"
  alignItems="stretch"
  autoColumns="auto"
  autoRows="auto"
  columnGap="2"
  gap="4"
  inline={false}
  justifyContent="start"
  justifyItems="start"
  placeContent="center"
  placeItems="center"
  rowGap="2"
  templateAreas="'header header header' 'body body body'"
  templateColumns="repeat(3, 1fr)"
  templateRows="auto"
/>
```

## `Grid` Props

`Grid` accepts every `div` prop, including `children`, `className`, `style`, and `ref`. The props below are optional. They are grouped by role.

### Container

These props configure the grid container. `gap`, `rowGap`, and `columnGap` use the spacing scale ([Spacing](https://anvil.servicetitan.com/docs/foundations/spacing.md)). Every other prop in this group maps to the CSS property named in its description. `inline` sets `display`.

**alignContent** `CSSProperties["alignContent"]`

Aligns the grid tracks along the block axis when the container has extra
space. Maps to `align-content`.

**alignItems** `CSSProperties["alignItems"]`

Aligns items along the block axis inside their grid areas. Maps to
`align-items`.

**autoColumns** `CSSProperties["gridAutoColumns"]`

Sets the size of implicit columns. Maps to `grid-auto-columns`.

**autoRows** `CSSProperties["gridAutoRows"]`

Sets the size of implicit rows. Maps to `grid-auto-rows`.

**columnGap** `GapSize`

Sets the column gap. Accepts a spacing step from `0` through `14`, or
`"half"`. Numbers and numeric strings match (`4` and `"4"`). Maps to
`column-gap`. See [Spacing](https://anvil.servicetitan.com/docs/foundations/spacing.md).

**gap** `GapSize`

Sets the row and column gaps together. Accepts a spacing step from `0`
through `14`, or `"half"`. Numbers and numeric strings match (`4` and
`"4"`). Maps to `gap`. See [Spacing](https://anvil.servicetitan.com/docs/foundations/spacing.md).

**inline** `boolean` (default: false)

Renders `display: inline-grid`. When `false`, `Grid` renders
`display: grid`.

**justifyContent** `CSSProperties["justifyContent"]`

Aligns the grid tracks along the inline axis when the container has extra
space. Maps to `justify-content`.

**justifyItems** `CSSProperties["justifyItems"]`

Aligns items along the inline axis inside their grid areas. Maps to
`justify-items`.

**placeContent** `CSSProperties["placeContent"]`

Sets `align-content` and `justify-content` together. Maps to
`place-content`.

**placeItems** `CSSProperties["placeItems"]`

Sets `align-items` and `justify-items` together. Maps to `place-items`.

**rowGap** `GapSize`

Sets the row gap. Accepts a spacing step from `0` through `14`, or
`"half"`. Numbers and numeric strings match (`4` and `"4"`). Maps to
`row-gap`. See [Spacing](https://anvil.servicetitan.com/docs/foundations/spacing.md).

**templateAreas** `CSSProperties["gridTemplateAreas"]`

Names grid areas for `gridArea` placement. Use CSS `grid-template-areas`
syntax, with each row quoted: `"'header header' 'sidebar content'"`. Maps
to `grid-template-areas`.

**templateColumns** `CSSProperties["gridTemplateColumns"]`

Defines the column tracks, including size and repeat patterns. Maps to
`grid-template-columns`.

**templateRows** `CSSProperties["gridTemplateRows"]`

Defines the row tracks, including size and repeat patterns. Maps to
`grid-template-rows`.

### Placement

```tsx theme={null}
<Grid templateColumns="1fr 1fr">
  <Grid gridColumn="1 / 3" alignSelf="start" order={0}>
    Nested grid
  </Grid>
</Grid>
```

These props place a `Grid` when it is a child of another grid. The same prop names exist on `Grid.Item`. `order` also applies when `Grid` is a flex item.

`gridColumn`, `gridRow`, and `order` change visual position only. DOM order stays the source order.

**alignSelf** `CSSProperties["alignSelf"]`

Aligns this element inside its grid area along the block axis, overriding
the container `alignItems`. Also applies when the element is a flex item.
Maps to `align-self`.

**gridArea** `CSSProperties["gridArea"]`

Places the element in a named area, or sets the row and column lines in
one value. Maps to `grid-area`.

**gridColumn** `CSSProperties["gridColumn"]`

Sets the column start and end lines. Shorthand for `gridColumnStart` and
`gridColumnEnd`. Maps to `grid-column`.

**gridColumnEnd** `CSSProperties["gridColumnEnd"]`

Sets the column end line. Maps to `grid-column-end`.

**gridColumnStart** `CSSProperties["gridColumnStart"]`

Sets the column start line. Maps to `grid-column-start`.

**gridRow** `CSSProperties["gridRow"]`

Sets the row start and end lines. Shorthand for `gridRowStart` and
`gridRowEnd`. Maps to `grid-row`.

**gridRowEnd** `CSSProperties["gridRowEnd"]`

Sets the row end line. Maps to `grid-row-end`.

**gridRowStart** `CSSProperties["gridRowStart"]`

Sets the row start line. Maps to `grid-row-start`.

**justifySelf** `CSSProperties["justifySelf"]`

Aligns this element inside its grid area along the inline axis,
overriding the container `justifyItems`. Maps to `justify-self`.

**order** `CSSProperties["order"]`

Sets the visual order of this element among its siblings. Does not change
DOM order. Maps to `order`.

**placeSelf** `CSSProperties["placeSelf"]`

Sets `align-self` and `justify-self` together. Maps to `place-self`.

### Flex item

```tsx theme={null}
<Flex>
  <Grid flex="1 1 auto" flexBasis="auto" flexGrow={1} flexShrink={1} />
</Flex>
```

These props apply when `Grid` is a child of a flex container, such as [Flex](https://anvil.servicetitan.com/docs/components/flex/web.md). `Grid` itself stays `display: grid` or `display: inline-grid`.

**flex** `CSSProperties["flex"]`

Sets the flex shorthand for grow, shrink, and basis. Maps to `flex`.

**flexBasis** `CSSProperties["flexBasis"]`

Sets the flex basis. Maps to `flex-basis`.

**flexDirection** `CSSProperties["flexDirection"]`

Sets `flex-direction` on this element. `Grid` renders as a grid, so this
property has no effect unless `style` or `className` changes `display` to
`flex`.

**flexGrow** `CSSProperties["flexGrow"]`

Sets how much the item grows when the flex container has extra space.
Maps to `flex-grow`.

**flexShrink** `CSSProperties["flexShrink"]`

Sets how much the item shrinks when the flex container overflows. Maps to
`flex-shrink`.

### Responsive

```tsx theme={null}
<Grid
  sm={{ templateColumns: "1fr" }}
  md={{ templateColumns: "repeat(2, 1fr)" }}
  lg={{ templateColumns: "repeat(3, 1fr)" }}
  xl={{ gap: "4" }}
  xxl={{ alignItems: "center" }}
/>
```

Each of `sm`, `md`, `lg`, `xl`, and `xxl` is `LayoutUtilProps` plus the track props (`templateColumns`, `templateRows`, `templateAreas`, `autoColumns`, `autoRows`). `LayoutUtilProps` includes nested `sm`, `md`, `lg`, `xl`, and `xxl` keys. Those nested keys type-check and are ignored at runtime. `inline` is not part of the breakpoint object.

`Grid.Item` breakpoint props are `Omit<LayoutUtilProps, "sm" | "md" | "lg" | "xl" | "xxl">`. They do not include track props or nested breakpoint keys.

**sm** `LayoutUtilProps & \{ templateColumns?: CSSProperties["gridTemplateColumns"]; templateRows?: CSSProperties["gridTemplateRows"]; templateAreas?: CSSProperties["gridTemplateAreas"]; autoColumns?: CSSProperties["gridAutoColumns"]; autoRows?: CSSProperties["gridAutoRows"] \}`

Applies at viewport widths of `640px` and wider.

**md** `LayoutUtilProps & \{ templateColumns?: CSSProperties["gridTemplateColumns"]; templateRows?: CSSProperties["gridTemplateRows"]; templateAreas?: CSSProperties["gridTemplateAreas"]; autoColumns?: CSSProperties["gridAutoColumns"]; autoRows?: CSSProperties["gridAutoRows"] \}`

Applies at viewport widths of `768px` and wider.

**lg** `LayoutUtilProps & \{ templateColumns?: CSSProperties["gridTemplateColumns"]; templateRows?: CSSProperties["gridTemplateRows"]; templateAreas?: CSSProperties["gridTemplateAreas"]; autoColumns?: CSSProperties["gridAutoColumns"]; autoRows?: CSSProperties["gridAutoRows"] \}`

Applies at viewport widths of `1024px` and wider.

**xl** `LayoutUtilProps & \{ templateColumns?: CSSProperties["gridTemplateColumns"]; templateRows?: CSSProperties["gridTemplateRows"]; templateAreas?: CSSProperties["gridTemplateAreas"]; autoColumns?: CSSProperties["gridAutoColumns"]; autoRows?: CSSProperties["gridAutoRows"] \}`

Applies at viewport widths of `1280px` and wider.

**xxl** `LayoutUtilProps & \{ templateColumns?: CSSProperties["gridTemplateColumns"]; templateRows?: CSSProperties["gridTemplateRows"]; templateAreas?: CSSProperties["gridTemplateAreas"]; autoColumns?: CSSProperties["gridAutoColumns"]; autoRows?: CSSProperties["gridAutoRows"] \}`

Applies at viewport widths of `1536px` and wider.

**Grid.Item Props**

```tsx theme={null}
<Grid templateColumns="repeat(3, 1fr)" gap="2">
  <Grid.Item gridColumn="span 2" alignSelf="center">
    Cell
  </Grid.Item>
  <Grid.Item>Cell</Grid.Item>
</Grid>
```

## `Grid.Item` Props

`Grid.Item` renders a `div` and accepts every `div` prop, including `children`, `className`, `style`, and `ref`.

It accepts the placement, flex, alignment, gap, and responsive props below. It does not accept `inline`, `templateColumns`, `templateRows`, `templateAreas`, `autoColumns`, or `autoRows` — set those on `Grid`.

Placement props position the cell in the parent grid. `flex`, `flexBasis`, `flexGrow`, and `flexShrink` apply when the parent is a flex container. `alignItems`, `justifyItems`, `alignContent`, `justifyContent`, `placeItems`, `placeContent`, `gap`, `rowGap`, `columnGap`, and `flexDirection` are written on the cell and take effect only when that cell's computed `display` is `grid` or `flex`. `Grid.Item` sets `display` to `revert-layer`, which computes to `block` for a `div` in a normal page. Set `display` with `style` or `className` when the cell itself must be a grid or flex container.

Layout props override the same CSS property on `style`.

### Placement

**alignSelf** `CSSProperties["alignSelf"]`

Aligns the cell inside its grid area along the block axis, overriding the
container `alignItems`. Also applies when the cell is a flex item. Maps
to `align-self`.

**gridArea** `CSSProperties["gridArea"]`

Places the cell in a named area, or sets the row and column lines in one
value. Maps to `grid-area`.

**gridColumn** `CSSProperties["gridColumn"]`

Sets the column start and end lines. Shorthand for `gridColumnStart` and
`gridColumnEnd`. Maps to `grid-column`.

**gridColumnEnd** `CSSProperties["gridColumnEnd"]`

Sets the column end line. Maps to `grid-column-end`.

**gridColumnStart** `CSSProperties["gridColumnStart"]`

Sets the column start line. Maps to `grid-column-start`.

**gridRow** `CSSProperties["gridRow"]`

Sets the row start and end lines. Shorthand for `gridRowStart` and
`gridRowEnd`. Maps to `grid-row`.

**gridRowEnd** `CSSProperties["gridRowEnd"]`

Sets the row end line. Maps to `grid-row-end`.

**gridRowStart** `CSSProperties["gridRowStart"]`

Sets the row start line. Maps to `grid-row-start`.

**justifySelf** `CSSProperties["justifySelf"]`

Aligns the cell inside its grid area along the inline axis, overriding
the container `justifyItems`. Maps to `justify-self`.

**order** `CSSProperties["order"]`

Sets the visual order of the cell among its siblings. Does not change DOM
order. Maps to `order`.

**placeSelf** `CSSProperties["placeSelf"]`

Sets `align-self` and `justify-self` together. Maps to `place-self`.

### Flex item

**flex** `CSSProperties["flex"]`

Sets the flex shorthand for grow, shrink, and basis when the parent is a
flex container. Maps to `flex`.

**flexBasis** `CSSProperties["flexBasis"]`

Sets the flex basis when the parent is a flex container. Maps to
`flex-basis`.

**flexDirection** `CSSProperties["flexDirection"]`

Sets `flex-direction` on the cell. Takes effect when the cell's `display`
is `flex`. Maps to `flex-direction`.

**flexGrow** `CSSProperties["flexGrow"]`

Sets how much the cell grows when its flex parent has extra space. Maps
to `flex-grow`.

**flexShrink** `CSSProperties["flexShrink"]`

Sets how much the cell shrinks when its flex parent overflows. Maps to
`flex-shrink`.

### Alignment and spacing

**alignContent** `CSSProperties["alignContent"]`

Sets `align-content` on the cell. Takes effect when the cell's `display`
is `grid` or `flex`.

**alignItems** `CSSProperties["alignItems"]`

Sets `align-items` on the cell. Takes effect when the cell's `display` is
`grid` or `flex`.

**columnGap** `GapSize`

Sets the column gap on the cell. Accepts a spacing step from `0` through
`14`, or `"half"`. Takes effect when the cell's `display` is `grid` or
`flex`. See [Spacing](https://anvil.servicetitan.com/docs/foundations/spacing.md).

**gap** `GapSize`

Sets the row and column gaps on the cell. Accepts a spacing step from `0`
through `14`, or `"half"`. Takes effect when the cell's `display` is
`grid` or `flex`. See [Spacing](https://anvil.servicetitan.com/docs/foundations/spacing.md).

**justifyContent** `CSSProperties["justifyContent"]`

Sets `justify-content` on the cell. Takes effect when the cell's
`display` is `grid` or `flex`.

**justifyItems** `CSSProperties["justifyItems"]`

Sets `justify-items` on the cell. Takes effect when the cell's `display`
is `grid`.

**placeContent** `CSSProperties["placeContent"]`

Sets `place-content` on the cell. Takes effect when the cell's `display`
is `grid` or `flex`.

**placeItems** `CSSProperties["placeItems"]`

Sets `place-items` on the cell. Takes effect when the cell's `display` is
`grid`.

**rowGap** `GapSize`

Sets the row gap on the cell. Accepts a spacing step from `0` through
`14`, or `"half"`. Takes effect when the cell's `display` is `grid` or
`flex`. See [Spacing](https://anvil.servicetitan.com/docs/foundations/spacing.md).

### Responsive

Breakpoint objects on `Grid.Item` use the same viewport widths as `Grid`. The published type is `Omit<LayoutUtilProps, "sm" | "md" | "lg" | "xl" | "xxl">`: every `Grid.Item` prop except the breakpoint props themselves. Unlike `Grid`, this object does not include track props or nested breakpoint keys.

**sm** `Omit\<LayoutUtilProps, "sm" | "md" | "lg" | "xl" | "xxl"\>`

Applies at viewport widths of `640px` and wider.

**md** `Omit\<LayoutUtilProps, "sm" | "md" | "lg" | "xl" | "xxl"\>`

Applies at viewport widths of `768px` and wider.

**lg** `Omit\<LayoutUtilProps, "sm" | "md" | "lg" | "xl" | "xxl"\>`

Applies at viewport widths of `1024px` and wider.

**xl** `Omit\<LayoutUtilProps, "sm" | "md" | "lg" | "xl" | "xxl"\>`

Applies at viewport widths of `1280px` and wider.

**xxl** `Omit\<LayoutUtilProps, "sm" | "md" | "lg" | "xl" | "xxl"\>`

Applies at viewport widths of `1536px` and wider.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.