Utilities
Add your own CSS properties, or remap existing ones to your tokens, with the utility API.
Panda ships a set of built-in utilities (bg, px, rounded, and the rest of what you already use in css()). The
utility API is how you add your own on top, or change what a built-in one does. Think of it as building your own
typed version of Tailwind's or Chakra's utility layer, except every value comes from your own config.
A utility takes these fields:
property: the real CSS property this utility maps to (borderRadius,backgroundColor, and so on).className: the class name Panda generates for it. Defaults to the property name if you skip it.shorthand: one alias, or an array of aliases, for the property (pxforpaddingInline, say).values: what values the property accepts. A token category name ('radii','colors'), an array of literal strings,{ type: 'boolean' }, or an object mapping your own keys to raw values.transform: a function that takes the value and returns the CSS object to emit.
Creating a custom utility
Say you want a br shorthand that applies a border radius:
panda.config.ts
import { defineConfig } from '@pandacss/dev'
export default defineConfig({
utilities: {
extend: {
br: {
className: 'rounded', // css({ br: 'sm' }) → .rounded_sm
values: 'radii', // pull values from the radii tokens
transform(value) {
return { borderRadius: value }
}
}
}
}
})Run codegen so the new property shows up in your generated types:
br now works everywhere css() does:
import { css } from '../styled-system/css'
function App() {
return <div className={css({ br: 'sm' })} />
}And as a JSX style prop:
import { styled } from '../styled-system/jsx'
function App() {
return <styled.div br="sm" />
}Enum values
Restrict a utility to a fixed set of raw values instead of a token category. Here, borderX only accepts three widths
and always sets the border color for you:
panda.config.ts
import { defineConfig } from '@pandacss/dev'
export default defineConfig({
utilities: {
extend: {
borderX: {
values: ['1px', '2px', '4px'],
shorthand: 'bx', // both `bx` and `borderX` work
transform(value, { token }) {
return {
borderInlineWidth: value,
borderColor: token('colors.red.200') // resolves to the CSS variable for red.200
}
}
}
}
}
})import { css } from '../styled-system/css'
function App() {
return <div className={css({ borderX: '2px' })} />
}Mapped values
Map your own keys to raw CSS values instead of a plain array:
panda.config.ts
import { defineConfig } from '@pandacss/dev'
export default defineConfig({
utilities: {
extend: {
borderX: {
values: { small: '2px', medium: '5px' },
shorthand: 'bx',
transform(value, { token }) {
return {
borderTopWidth: value,
borderTopColor: token('colors.gray.400')
}
}
}
}
}
})Now borderX: 'small' resolves to 2px, not the literal string 'small'.
Boolean values
Set values: { type: 'boolean' } for a utility that's either on or off:
panda.config.ts
import { defineConfig } from '@pandacss/dev'
export default defineConfig({
utilities: {
extend: {
truncate: {
className: 'truncate',
values: { type: 'boolean' },
transform(value) {
if (!value) return {}
return {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
}
}
}
}
}
})css({ truncate: true }) now emits the three declarations above. truncate: false emits nothing.
Starting from zero
Everything here assumes you're extending Panda's defaults with utilities.extend. If you want no built-in utilities
at all and full control from the start, see minimal setup.