Skip to main content
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.
1

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.
import { AnvilProvider } from "@servicetitan/anvil2";

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

Import the utility stylesheets

Import the full bundle or only the categories you need:
// 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";
3

Apply classes to elements inside AnvilProvider

Add a2-* classes through className on Anvil2 components or plain HTML elements:
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>
  );
}
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.

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 for details on CSS utility scoping.

Available stylesheets

StylesheetImport pathContents
a2-utils.css@servicetitan/anvil2/assets/css-utils/a2-utils.cssAll utility classes
a2-spacing.css@servicetitan/anvil2/assets/css-utils/a2-spacing.cssMargin and padding
a2-color.css@servicetitan/anvil2/assets/css-utils/a2-color.cssBackground, text, and border colors
a2-border.css@servicetitan/anvil2/assets/css-utils/a2-border.cssBorder radius and width
a2-font.css@servicetitan/anvil2/assets/css-utils/a2-font.cssFont family, size, and weight
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.
The authoritative class list lives in the anvil2 css-utils source directory.

When to use CSS utilities

Prefer Anvil2 components and their props before reaching for CSS utilities:
NeedRecommended approach
Flexbox or Grid layoutFlex or Grid
Responsive layout on componentsLayout props
TypographyText
Spacing inside a component treeComponent gap, padding, or margin props where available
One-off margin, padding, color, or borderCSS 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 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.
PatternCSS propertyExample
a2-m-{size}margin (all sides)a2-m-4
a2-m-{direction}-{size}margin on one axis or sidea2-m-inline-start-4
a2-p-{size}padding (all sides)a2-p-half
a2-p-{direction}-{size}padding on one axis or sidea2-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.

Colors (a2-color.css)

Color utilities set background-color, color, or border-color from semantic tokens.
PrefixCSS propertyExample
a2-bg-*background-colora2-bg-primary-hover
a2-c-*colora2-c-subdued
a2-border-color-*border-colora2-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)

PrefixValues
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)

PrefixCSS propertyValues
a2-ff-*font-familyheading, label, paragraph
a2-fw-*font-weightheading, label, paragraph
a2-fs-*font-size{heading|label|paragraph}-{xsmall|small|default|large|xlarge}
For styled text in product UI, prefer the Text component. Typography utilities are useful for plain HTML or custom markup.

Accessibility

ClassPurpose
sr-onlyVisually 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 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.
Last modified on June 18, 2026