Overview
A guide for configuring the Chakra UI theming system.
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: {
tokens: {
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 breakpointskeyframes
: for defining css keyframes animationstokens
: for defining tokenssemanticTokens
: for defining semantic tokenstextStyles
: for defining typography styleslayerStyles
: for defining layer stylesanimationStyles
: for defining animation stylesrecipes
: for defining component recipesslotRecipes
: 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 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.tokens.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.