Skip to Content
DocsEnterpriseBlogShowcase

Overview

A guide for configuring the Chakra UI theming system.

SourceStorybookRecipe

Architecture

The Chakra UI theming system is built around the API of Panda CSS.

Here's a quick overview of how the system is structured to provide a performant and extensible styling system:

  • Define the styling system configuration using the defineConfig function
  • Create the styling engine using the createSystem function
  • Pass the styling engine to the ChakraProvider component
import { ChakraProvider, createSystem } from "@chakra-ui/react"

const config = defineConfig({
  theme: {
    colors: {},
  },
})

const system = createSystem(config)

export default function App() {
  return (
    <ChakraProvider value={system}>
      <Box>Hello World</Box>
    </ChakraProvider>
  )
}

Config

The Chakra UI system is configured using the defineConfig function. This function accepts a configuration object that allows you to customize the styling system's behavior.

After a config is defined, it is passed to the createSystem function to create the styling engine.

cssVarsRoot

cssVarsRoot is the root element where the token CSS variables will be applied.

theme.ts

const config = defineConfig({
  cssVarsRoot: ":where(:root, :host)",
})

export default createSystem(config)

cssVarsPrefix

cssVarsPrefix is the prefix used for the token CSS variables.

theme.ts

const config = defineConfig({
  cssVarsPrefix: "ck",
})

export default createSystem(config)

globalCss

globalCss is used to apply global styles to the system.

theme.ts

const config = defineConfig({
  globalCss: {
    "html, body": {
      margin: 0,
      padding: 0,
    },
  },
})

export default createSystem(config)

theme

Use the theme config property to define the system theme. This property accepts the following properties:

  • breakpoints: for defining breakpoints
  • keyframes: for defining css keyframes animations
  • tokens: for defining tokens
  • semanticTokens: for defining semantic tokens
  • textStyles: for defining typography styles
  • layerStyles: for defining layer styles
  • animationStyles: for defining animation styles
  • recipes: for defining component recipes
  • slotRecipes: for defining component slot recipes

theme.ts

const config = defineConfig({
  theme: {
    breakpoints: {
      sm: "320px",
      md: "768px",
      lg: "960px",
      xl: "1200px",
    },
    tokens: {
      colors: {
        red: "#EE0F0F",
      },
    },
    semanticTokens: {
      colors: {
        danger: { value: "{colors.red}" },
      },
    },
    keyframes: {
      spin: {
        from: { transform: "rotate(0deg)" },
        to: { transform: "rotate(360deg)" },
      },
    },
  },
})

export default createSystem(config)

conditions

Use the conditions config property to define custom selectors and media query conditions for use in the system.

theme.ts

const config = defineConfig({
  conditions: {
    cqSm: "@container(min-width: 320px)",
    child: "& > *",
  },
})

export default createSystem(config)

Sample usage:

<Box mt="40px" _cqSm={{ mt: "0px" }}>
  <Text>Hello World</Text>
</Box>

strictTokens

Use the strictTokens config property to enforce the usage of only design tokens. This will throw a TS error if you try to use a token that is not defined in the theme.

theme.ts

const config = defineConfig({
  strictTokens: true,
})

export default createSystem(config)
// ❌ This will throw a TS error
<Box color="#4f343e">Hello World</Box>

// ✅ This will work
<Box color="red.400">Hello World</Box>

TypeScript

When you configure the system properties (like colors, space, fonts, etc.), the CLI can be used to generate type definitions for them.

npx @chakra-ui/cli@next typegen ./theme.ts

This will update the internal types in the @chakra-ui/react package, and make sure they are in sync with the theme. Providing a type-safe API and delightful experience for developers.

System

After a config is defined, it is passed to the createSystem function to create the styling engine. The returned system is framework-agnostic JavaScript styling engine that can be used to style components.

const system = createSystem(config)

The system includes the following properties:

token

The token function is used to get a raw token value, or css variable.

const system = createSystem(config)

// raw token
system.token("colors.red.200")
// => "#EE0F0F"

// token with fallback
system.token("colors.pink.240", "#000")
// => "#000"

Use the token.var function to get the css variable:

// css variable
system.token.var("colors.red.200")
// => "var(--chakra-colors-red-200)"

// token with fallback
system.token.var("colors.pink.240", "colors.red.200")
// => "var(--chakra-colors-red-200)"

It's important to note that semanticTokens always return a css variable, regardless of whether you use token or token.var. This is because semantic tokens change based on the theme.

// semantic token
system.token("colors.danger")
// => "var(--chakra-colors-danger)"

system.token.var("colors.danger")
// => "var(--chakra-colors-danger)"

tokens

const system = createSystem(config)

system.tokens.getVar("colors.red.200")
// => "var(--chakra-colors-red-200)"

system.tokens.expandReferenceInValue("3px solid {colors.red.200}")
// => "3px solid var(--chakra-colors-red-200)"

system.tokens.cssVarMap
// => Map { "colors": Map { "red.200": "var(--chakra-colors-red-200)" } }

system.flatMap
// => Map { "colors.red.200": "var(--chakra-colors-red-200)" }

css

The css function is used to convert chakra style objects to CSS style object that can be passed to emotion or styled-components or any other styling library.

const system = createSystem(config)

system.css({
  color: "red.200",
  bg: "blue.200",
})

// => { color: "var(--chakra-colors-red-200)", background: "var(--chakra-colors-blue-200)" }

cva

The cva function is used to create component recipes. It returns a function that, when called with a set of props, returns a style object.

const system = createSystem(config)

const button = system.cva({
  base: {
    color: "white",
    bg: "blue.500",
  },
  variants: {
    outline: {
      color: "blue.500",
      bg: "transparent",
      border: "1px solid",
    },
  },
})

button({ variant: "outline" })
// => { color: "blue.500", bg: "transparent", border: "1px solid" }

sva

The sva function is used to create component slot recipes. It returns a function that, when called with a set of props, returns a style object for each slot.

const system = createSystem(config)

const alert = system.sva({
  slots: ["title", "description", "icon"],
  base: {
    title: { color: "white" },
    description: { color: "white" },
    icon: { color: "white" },
  },
  variants: {
    status: {
      info: {
        title: { color: "blue.500" },
        description: { color: "blue.500" },
        icon: { color: "blue.500" },
      },
    },
  },
})

alert({ status: "info" })
// => { title: { color: "blue.500" }, description: { color: "blue.500" }, icon: { color: "blue.500" } }

isValidProperty

The isValidProperty function is used to check if a property is valid.

const system = createSystem(config)

system.isValidProperty("color")
// => true

system.isValidProperty("background")
// => true

system.isValidProperty("invalid")
// => false

splitCssProps

The splitCssProps function is used to split the props into css props and non-css props.

const system = createSystem(config)

system.splitCssProps({
  color: "red.200",
  bg: "blue.200",
  "aria-label": "Hello World",
})
// => [{ color: "red.200", bg: "blue.200" }, { "aria-label": "Hello World" }]

breakpoints

The breakpoints property is used to query breakpoints.

const system = createSystem(config)

system.breakpoints.up("sm")
// => "@media (min-width: 320px)"

system.breakpoints.down("sm")
// => "@media (max-width: 319px)"

system.breakpoints.only("md")
// => "@media (min-width: 320px) and (max-width: 768px)"

system.breakpoints.keys()
// => ["sm", "md", "lg", "xl"]

Tokens

To learn more about tokens, please refer to the tokens section.

Recipes

To learn more about recipes, please refer to the recipes section.