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

# CSS Utilities

> Reference for Anvil2 CSS utility classes and how to add them to your project.

Anvil2 ships a set of CSS utility classes for applying design tokens to layout, color, typography, and borders. Use these classes when a component prop or layout utility does not cover your styling need.

## Add CSS utilities to your project

Anvil2 component CSS is bundled per component. CSS utility stylesheets are separate imports that you add only when you use utility classes. Import stylesheets directly at your app entry point or in any module that uses utility classes; `AnvilProvider` does not load them automatically.

<Warning>
  `AnvilProvider` briefly shipped a `cssUtils` prop for automatic stylesheet loading in `3.4.2`. That prop is deprecated and no longer has any effect: automatically loading CSS through a dynamic import broke stylesheet delivery when `AnvilProvider` is shared between a host application and its micro-frontends. Import the stylesheets you need directly, as shown below.
</Warning>

<Steps>
  <Step title="Wrap your app in AnvilProvider">
    `AnvilProvider` applies the `anvil2` class to your app and injects theme tokens. Published utility rules are scoped to elements inside that container.

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

    export function App() {
      return (
        <AnvilProvider>
          {/* Your app */}
        </AnvilProvider>
      );
    }
    ```
  </Step>

  <Step title="Import the utility stylesheets">
    Import the full bundle or only the categories you need:

    ```tsx theme={null}
    // All utilities (~387 classes)
    import "@servicetitan/anvil2/assets/css-utils/a2-utils.css";

    // Or import by category for a smaller bundle
    import "@servicetitan/anvil2/assets/css-utils/a2-spacing.css";
    import "@servicetitan/anvil2/assets/css-utils/a2-color.css";
    import "@servicetitan/anvil2/assets/css-utils/a2-border.css";
    import "@servicetitan/anvil2/assets/css-utils/a2-font.css";
    ```
  </Step>

  <Step title="Apply classes to elements inside AnvilProvider">
    Add `a2-*` classes through `className` on Anvil2 components or plain HTML elements:

    ```tsx theme={null}
    import { AnvilProvider, Card } from "@servicetitan/anvil2";
    import "@servicetitan/anvil2/assets/css-utils/a2-utils.css";

    export function Example() {
      return (
        <AnvilProvider>
          <Card className="a2-m-inline-4 a2-bg-default">
            Card with inline margin and default background
          </Card>
        </AnvilProvider>
      );
    }
    ```
  </Step>
</Steps>

<Note>
  Utility classes use CSS custom properties from the Anvil2 theme. `AnvilProvider` injects the active theme values. Fallback values are included in each rule so limited styling works outside a provider, but light/dark mode requires `AnvilProvider`.
</Note>

## Scoping

Starting in Anvil2 3.0, every published utility rule is scoped under `.anvil2`. A class such as `a2-m-4` only matches elements inside an `anvil2` container.

`AnvilProvider` adds the `anvil2` class automatically. If you cannot use `AnvilProvider`, add the `anvil2` class to an ancestor of the elements that use utility classes.

Portaled content (dialogs, popovers, toasts) also needs the `anvil2` scope. `AnvilProvider` mirrors the class on `document.body` for this reason. See the [2.0 to 3.0 migration guide](/docs/resources/migration-guides/2.0-to-3.0) for details on CSS utility scoping.

## Available stylesheets

| Stylesheet       | Import path                                            | Contents                            |
| ---------------- | ------------------------------------------------------ | ----------------------------------- |
| `a2-utils.css`   | `@servicetitan/anvil2/assets/css-utils/a2-utils.css`   | All utility classes                 |
| `a2-spacing.css` | `@servicetitan/anvil2/assets/css-utils/a2-spacing.css` | Margin and padding                  |
| `a2-color.css`   | `@servicetitan/anvil2/assets/css-utils/a2-color.css`   | Background, text, and border colors |
| `a2-border.css`  | `@servicetitan/anvil2/assets/css-utils/a2-border.css`  | Border radius and width             |
| `a2-font.css`    | `@servicetitan/anvil2/assets/css-utils/a2-font.css`    | Font family, size, and weight       |

<Warning>
  Legacy stylesheets without the `a2-` prefix (`utils.css`, `spacing.css`, and so on) are deprecated. Use the `a2-*` class names and stylesheets in new code.
</Warning>

The authoritative class list lives in the [anvil2 css-utils source directory](https://github.com/servicetitan/hammer/tree/main/packages/anvil2/public/assets/css-utils).

## When to use CSS utilities

Prefer Anvil2 components and their props before reaching for CSS utilities:

| Need                                      | Recommended approach                                                                 |
| ----------------------------------------- | ------------------------------------------------------------------------------------ |
| Flexbox or Grid layout                    | [`Flex`](/docs/web/components/flex/code) or [`Grid`](/docs/web/components/grid/code) |
| Responsive layout on components           | [Layout props](/docs/web/utilities/layout-props)                                     |
| Typography                                | [`Text`](/docs/web/components/text/code)                                             |
| Spacing inside a component tree           | Component `gap`, `padding`, or `margin` props where available                        |
| One-off margin, padding, color, or border | CSS utility classes                                                                  |

Anvil2 intentionally removed many Anvil1 utility categories (flex, grid, display, position, alignment, height, width, z-index, line height, and white space). Use components or layout props for those cases. See the [Anvil to Anvil2 migration guide](/docs/resources/migration-guides/anvil-to-anvil2#css-utilities) for the full list of changes.

## Class naming conventions

All recommended utility classes use the `a2-` prefix. Each class maps to a design token through a `--a2-*` CSS custom property.

### Spacing (`a2-spacing.css`)

Spacing utilities set `margin` or `padding` using logical properties for internationalization.

| Pattern                   | CSS property                | Example               |
| ------------------------- | --------------------------- | --------------------- |
| `a2-m-{size}`             | margin (all sides)          | `a2-m-4`              |
| `a2-m-{direction}-{size}` | margin on one axis or side  | `a2-m-inline-start-4` |
| `a2-p-{size}`             | padding (all sides)         | `a2-p-half`           |
| `a2-p-{direction}-{size}` | padding on one axis or side | `a2-p-block-start-2`  |

**Size values:** `0`, `quarter`, `half`, `1` through `14`

**Directions:** `inline-start`, `inline-end`, `block-start`, `block-end`, `inline`, `block`, or omit for all sides

Spacing values use `rem` units. Token values are documented on the [Spacing foundations page](/docs/web/foundations/spacing#spacing-tokens).

### Colors (`a2-color.css`)

Color utilities set `background-color`, `color`, or `border-color` from semantic tokens.

| Prefix                     | CSS property                | Example                       |
| -------------------------- | --------------------------- | ----------------------------- |
| `a2-bg-*`                  | `background-color`          | `a2-bg-primary-hover`         |
| `a2-c-*`                   | `color`                     | `a2-c-subdued`                |
| `a2-border-color-*`        | `border-color`              | `a2-border-color-danger`      |
| `a2-bg-status-*`           | `background-color` (status) | `a2-bg-status-success`        |
| `a2-c-status-*`            | `color` (status)            | `a2-c-status-warning`         |
| `a2-border-color-status-*` | `border-color` (status)     | `a2-border-color-status-info` |

**Semantic roles:** `default`, `primary`, `secondary`, `danger`, `success`, `warning`, `inverted`, `disabled`, `transparent-*`

**Interactive suffixes:** `-hover`, `-active`, `-faint`, `-subdued`, and combinations such as `-subdued-hover`

**Status values:** `danger`, `info`, `success`, `warning`

**On-color text:** `a2-c-on-primary`, `a2-c-on-danger`, and related variants for text on colored backgrounds

### Borders (`a2-border.css`)

| Prefix               | Values                                                                    |
| -------------------- | ------------------------------------------------------------------------- |
| `a2-border-radius-*` | `none`, `small`, `medium`, `large`, `xlarge`, `circular`                  |
| `a2-border-width-*`  | `none`, `default`, `strong`                                               |
| `a2-border-color-*`  | `default`, `subdued`, `strong`, `primary`, `danger`, `success`, `warning` |

### Typography (`a2-font.css`)

| Prefix    | CSS property  | Values                                                                |
| --------- | ------------- | --------------------------------------------------------------------- |
| `a2-ff-*` | `font-family` | `heading`, `label`, `paragraph`                                       |
| `a2-fw-*` | `font-weight` | `heading`, `label`, `paragraph`                                       |
| `a2-fs-*` | `font-size`   | `{heading\|label\|paragraph}-{xsmall\|small\|default\|large\|xlarge}` |

For styled text in product UI, prefer the [`Text`](/docs/web/components/text/code) component. Typography utilities are useful for plain HTML or custom markup.

### Accessibility

| Class     | Purpose                                                             |
| --------- | ------------------------------------------------------------------- |
| `sr-only` | Visually hides content while keeping it available to screen readers |

`sr-only` is the only utility class without the `a2-` prefix. It is included in `a2-utils.css`.

## Troubleshooting

### Utility classes have no effect

Check these conditions in order:

1. **Missing `anvil2` scope** — Confirm the element is inside an `AnvilProvider` or an ancestor with the `anvil2` class.
2. **Missing stylesheet import** — Import at least one css-utils stylesheet in your app entry or the module that uses the classes.
3. **Legacy class names** — Replace unprefixed classes (for example `m-4`) with `a2-*` equivalents (`a2-m-4`).
4. **Legacy CSS overrides** — Some monolith CSS can override Anvil2 utilities. If a class appears in the stylesheet but not in the browser, wrap custom styles in an `@layer application` block. See the [Anvil2 README](https://github.com/servicetitan/hammer/blob/main/packages/anvil2/README.md#css-utils) for the workaround.

### Theme colors look wrong

Verify `AnvilProvider` wraps the tree that contains the styled elements. Utility classes read `--a2-*` variables injected by the theme provider.

## Related documentation

* [Spacing tokens](/docs/web/foundations/spacing#spacing-tokens) — spacing scale values used by `a2-m-*` and `a2-p-*` classes
* [Theming](/docs/web/foundations/theming) — how design tokens and themes work in Anvil2
* [Anvil to Anvil2 migration: CSS Utilities](/docs/resources/migration-guides/anvil-to-anvil2#css-utilities) — class renames and removed categories from Anvil1
