> ## 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.

# Layout - Web

> Define page layout structure and columns.

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

![](https://mintcdn.com/servicetitan/uz2PQSvO75TRhQ38/images/docs/web/components/shared/overview-of-a-layout-component.png?fit=max\&auto=format\&n=uz2PQSvO75TRhQ38\&q=85\&s=1628df91a3ec4cd4877f873f9cb7b690)

## Anatomy

The Layout consists of two primary elements that work together to define page structure and columns.

![Layout
Anatomy](https://mintcdn.com/servicetitan/CekIMDXcDEhGoN_I/images/docs/web/components/layout/design/layout-anatomy.png?fit=max\&auto=format\&n=CekIMDXcDEhGoN_I\&q=85\&s=bd68b43041a0c44258f3199d69e56b91)

1. Gutter
2. Column

## Options

The Layout supports responsive column configurations, width options, and gutter variants to accommodate various page structure scenarios.

### Columns per breakpoint

\| Breakpoint     | # of columns |

\| -------------- | ------------ |
\| SM `>=640px`   | 4            |
\| MD `>=768px`   | 6            |
\| LG `>=1024px`  | 12           |
\| XL `>=1280px`  | 12           |
\| XXL `>=1536px` | 12           |

### Width

There are two width options available: Default (fixed) and Fluid.

#### Default

By default, Layout is fixed: it has a max width of 1280px and centers on the page. Below 1280px, it fills the available width.

#### Fluid

When Layout is fluid, Layout removes the 1280px max width and fills the available area at every screen size.

### Variants

There are three variants of Layout: Default, Wide, and Narrow. Each variant has different gutter values. Gutters are the spacing between columns.

#### Default

| Breakpoint | Gutter |
| - | - |
| SM `>=640px` | \$size-4 / 1rem / 16px |
| MD `>=768px` | \$size-6 / 1.5rem / 24px |
| LG `>=1024px` | \$size-6 / 1.5rem / 24px |
| XL `>=1280px` | \$size-6 / 1.5rem / 24px |
| XXL `>=1536px` | \$size-6 / 1.5rem / 24px |

#### Wide

| Breakpoint | Gutter |
| - | - |
| SM `>=640px` | \$size-6 / 1.5rem / 24px |
| MD `>=768px` | \$size-8 / 2rem / 32px |
| LG `>=1024px` | \$size-10 / 2.5rem / 40px |
| XL `>=1280px` | \$size-10 / 2.5rem / 40px |
| XXL `>=1536px` | \$size-10 / 2.5rem / 40px |

#### Narrow

| Breakpoint | Gutter |
| - | - |
| SM `>=640px` | \$size-2 / 0.5rem / 8px |
| MD `>=768px` | \$size-4 / 1rem / 16px |
| LG `>=1024px` | \$size-4 / 1rem / 16px |
| XL `>=1280px` | \$size-4 / 1rem / 16px |
| XXL `>=1536px` | \$size-4 / 1rem / 16px |

## Behavior

The Layout responds to different breakpoints and content requirements while maintaining consistent column structure.

## Usage Guidelines

\| Standard                                                                                                             | Requirement                                                                                                                                                                                                                                                                                                                         |

| Standard | Requirement |
| - | - |
| DoStructure the overall page | Use the Layout to construct the overall structure of a page. Place section content directly in each Layout Item; a Layout Item does not need a Card. Use a [Card](https://anvil.servicetitan.com/docs/components/card/web.md#usage-guidelines) inside a Layout Item only for a peer tile, a chart, or an isolated group without a section heading. |
| DoPlace as the first child for page structure | A page body needs its overall column structure; place the Layout as the first child of the Page's main content. |
| DoDivide a page into columns | When the page divides into columns, each column holds its own content. |
| DoUse a Layout Item for full-width content | Even a lone table or Alert belongs in a Layout Item that spans all 12 columns, so the content lines up with the Page Header on wide screens. |
| DoStart with fixed width | Start with the default fixed layout. Choose fluid only when the page's primary content needs more than 1280px of width on large screens. |
| DoUse fixed layout for most pages | Use the default fixed layout for most pages, including dashboards, forms, detail pages, and list pages. Fixed layouts optimize readability on larger screens by limiting line lengths and provide greater design control. Both widths are responsive: below 1280px, a fixed layout fills the available width just like a fluid one. |
| DoUse fluid layout for wide content | Use a fluid layout when the primary content is wide enough to use the space beyond 1280px, such as a data table with many columns, a scheduling board, or a map. Fluid layouts maximize available screen space on large monitors. |
| DoUse default gutters for balanced layouts | Use the default gutter variant for balanced layouts with standard spacing between columns. This variant provides a neutral aesthetic that works well across content types and screen sizes, ensuring consistent visual flow and stable visual hierarchy. |
| DoUse narrow gutters for dense layouts | Choose the narrow gutter variant for compact, dense layouts where maximizing content visibility is crucial. Narrow gutters focus user attention on specific content elements and help create cohesive groupings. They work well for mobile-friendly designs where screen space is limited. |
| DoUse wide gutters for spacious layouts | Use the wide gutter variant to create spacious layouts with larger gutters between columns. Wide gutters provide breathing room around content elements, visually separate different sections, and enhance readability for text-heavy interfaces or long-form content. |
| DoMatch gutters to context | Consider user context and content type when selecting a gutter variant. Ensure the chosen variant adapts responsively across devices and screen sizes, and test layouts to confirm designs remain effective on both desktop and mobile devices. |
| Don'tOrganize elements within other containers | Layout is not used for organizing elements within other containers. For smaller UI layouts within a section or inside another container, such as a Card, use [Grid](https://anvil.servicetitan.com/docs/components/grid/web.md) or [Flex](https://anvil.servicetitan.com/docs/components/flex/web.md) instead. |
| Don'tUse fluid layout for density alone | A dense page doesn't need a fluid layout on its own. Density sets how much content a page shows, while width sets how far that content stretches on large screens. When you use a fluid layout, set `fluid` on both the `Page.Header` `layout` prop and the `Layout` inside `Page.Content` so their edges align. |

## Content

Content within the Layout should be organized using the column structure to create clear visual hierarchy.

## Keyboard Interaction

Users can navigate the Layout using standard keyboard controls.

## Code

**Implementation**

layout-playground

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

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

function App() {
  const cardProps = {
    background: "stronger" as const,
    style: { width: "100%" },
  };
  const createArray = (number: number) => [...new Array(number)];

  return (
    <div style={{ width: "calc(100vw - 4rem)" }}>
      <Layout variant="narrow">
        <Layout.Item span={12}>
          <Card {...cardProps}>span=12</Card>
        </Layout.Item>
        {createArray(2).map((_, i) => (
          <Layout.Item key={i} span={6}>
            <Card {...cardProps}>span=6</Card>
          </Layout.Item>
        ))}
        {createArray(3).map((_, i) => (
          <Layout.Item key={i} span={4}>
            <Card {...cardProps}>span=4</Card>
          </Layout.Item>
        ))}
        {createArray(4).map((_, i) => (
          <Layout.Item key={i} span={3}>
            <Card {...cardProps}>span=3</Card>
          </Layout.Item>
        ))}
        {createArray(6).map((_, i) => (
          <Layout.Item key={i} span={2}>
            <Card {...cardProps}>span=2</Card>
          </Layout.Item>
        ))}
        {createArray(12).map((_, i) => (
          <Layout.Item key={i} span={1}>
            <Card justifyContent="center" {...cardProps}>
              1
            </Card>
          </Layout.Item>
        ))}
      </Layout>
    </div>
  );
}

export default App;
```

## Common Examples

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

const ExampleComponent = () => (
  <Layout>
    <Layout.Item span={12}>{/* full-width content... */}</Layout.Item>
    <Layout.Item span={3}>{/* one-quarter-width content... */}</Layout.Item>
    <Layout.Item span={9}>{/* three-quarter-width content... */}</Layout.Item>
  </Layout>
);
```

### Using layouts in pages

In general, the `Layout` component is intended to be used as the child of a [Page.Content](https://anvil.servicetitan.com/docs/components/page/code#page-components) component. Using these components together creates the foundation of page layouts in Anvil2.

layout-page-full-page

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

```tsx lines expandable theme={null}
import { Flex, Layout, Page, Text } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ width: "100vw", height: "100vh" }}>
      <Page style={{ margin: "-1.5rem" }}>
        <Page.Sidebar>
          <Page.SidebarHeader>
            <Text variant="headline" el="h2">
              Sidebar
            </Text>
          </Page.SidebarHeader>
        </Page.Sidebar>
        <Page.Content>
          <Layout variant="narrow">
            <Layout.Item span={12}>
              <Flex direction="column" gap="2">
                <Text variant="headline" el="h2">
                  Layout
                </Text>
                <Text>
                  Place page sections directly in a Layout Item, separated by
                  headings and spacing.
                </Text>
              </Flex>
            </Layout.Item>
          </Layout>
        </Page.Content>
      </Page>
    </div>
  );
}

export default App;
```

### Fixed and fluid layouts

By default, layouts are fixed, meaning that they have a maximum width of `1280px` and are centered on the page. On smaller screens, they become fluid and fill the width of the page.

```tsx theme={null}
// max-width: 1280px
<Layout>
  <Layout.Item span={12}>{/* content... */}</Layout.Item>
</Layout>
```

Set the `fluid` prop to `true` when the primary content needs more than `1280px` on large screens. See [Layout usage guidelines](https://anvil.servicetitan.com/docs/components/layout/design#usage-guidelines) to decide.

```tsx theme={null}
// max-width: none
<Layout fluid>
  <Layout.Item span={12}>{/* content... */}</Layout.Item>
</Layout>
```

### Responsive layouts

Layout items come with responsive styles baked-in. As the parent layout becomes more narrow, the layout items will adjust accordingly based on the [number of columns available in that breakpoint](https://anvil.servicetitan.com/docs/components/layout/design#columns-per-breakpoint).

For example, a `Layout.Item` with `span={4}` will take up a third of the width on breakpoints `lg`, `xl`, and `xxl`, two-thirds on the `md` breakpoint, and full-width on `sm` breakpoint and below.

**Note –** these breakpoints correspond to the size of the layout rather than the screen, using container queries. Sidebars and panels may also affect the number of columns displayed.

The `Layout.Item` also features responsive props, which can be used to override the `span` value at specific breakpoints. See the [Layout.Item Props](#layout-item-props) for details.

### Layout density variants

Use the `variant` prop of the `Layout` component to control the gap between the layout items. Note that the gap will also change based on the width of the layout.

#### Narrow

layout-variant-narrow

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

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

function App() {
  return (
    <div style={{ width: "calc(100vw - 4rem)" }}>
      <Layout variant="narrow">
        {[...new Array(4)].map((_, i) => (
          <Layout.Item key={i} span={2}>
            <Card background="strong" style={{ width: "100%" }} />
          </Layout.Item>
        ))}
      </Layout>
    </div>
  );
}

export default App;
```

#### Default

layout-variant

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

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

function App() {
  return (
    <div style={{ width: "calc(100vw - 4rem)" }}>
      <Layout>
        {[...new Array(4)].map((_, i) => (
          <Layout.Item key={i} span={2}>
            <Card background="strong" style={{ width: "100%" }} />
          </Layout.Item>
        ))}
      </Layout>
    </div>
  );
}

export default App;
```

#### Wide

layout-variant-wide

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

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

function App() {
  return (
    <div style={{ width: "calc(100vw - 4rem)" }}>
      <Layout variant="wide">
        {[...new Array(4)].map((_, i) => (
          <Layout.Item key={i} span={2}>
            <Card background="strong" style={{ width: "100%" }} />
          </Layout.Item>
        ))}
      </Layout>
    </div>
  );
}

export default App;
```

## Best Practices

* Use the `Layout` component as the first child of the [Page.Content](https://anvil.servicetitan.com/docs/components/page/code#page-components) component.
* Use layouts to appropriately divide a page into columns, then use the [Grid](https://anvil.servicetitan.com/docs/components/grid/code/) and [Flex](https://anvil.servicetitan.com/docs/components/flex/code/) components to create smaller UI layouts within the content of the page.
* Place content directly in `Layout.Item`. The span and variant examples above use `Card` only to visualize columns. See [Card usage guidelines](https://anvil.servicetitan.com/docs/components/card/design#usage-guidelines).

**Layout Props**

```tsx theme={null}
<Layout fluid={false} variant="default">
  <Layout.Item span={12}>Content</Layout.Item>
</Layout>
```

## `Layout` Props

In addition to the props listed below, the `Layout` component can accept any valid HTML `div` props.

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

Removes the `1280px` max width so the layout fills the available width. Leave unset unless the primary content needs the extra width.

**variant** `"default" | "narrow" | "wide"` (default: default)

**Layout.Item Props**

```tsx theme={null}
<Layout.Item span={12} xs={12} sm={6} md={4} lg={3} xl={2} xxl={1}>
  Content
</Layout.Item>
```

## `Layout.Item` Props

The `Layout.Item` component can accept any valid HTML `div` props, as well as the following:

**span** `0 - 12` (default: 12)

Override span value below sm breakpoint

**xs** `0 - 12`

Override `span` value below `sm` breakpoint

**sm** `0 - 12`

Override `span` value for `sm` breakpoint

**md** `0 - 12`

Override `span` value for `md` breakpoint

**lg** `0 - 12`

Override `span` value for `lg` breakpoint

**xl** `0 - 12`

Override `span` value for `xl` breakpoint

**xxl** `0 - 12`

Override `span` value for `xxl` breakpoint


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