Semantic Tokens
Chakra UI supports conditional semantic tokens for every scale (colors, font sizes, etc). This allows to change the value of a token depending on the environment, like dark mode, direction and other CSS selectors.
We are using CSS variables which can change with a CSS condition. E.g. the color
token text can have a different value in dark and light mode.
Token References
A semantic token value can be a string | SemanticValue. The string value is
used as reference to another token in the same scale e.g.
{
error: 'red.500';
}
Conditional Tokens
The object notation SemanticValue allows to define the default value and
conditional keys. The condition can be one of
chakra pseudo selectors or a
custom CSS selector. Try _dark, _light, _rtl, _ltr and
_mediaReduceMotion.
If you are tempted to use a CSS selector like _focus, _hover etc. define
those CSS variables at the component level.
The CSS variables are attached to the host element (CSS selector :host, :root)
and cannot react to the components <LightMode /> and <DarkMode />,
data-theme attributes nor body class .chakra-ui-dark. It listens to e.g.
html[data-theme="dark"].
Since the CSS variables are attached to the host element by default we can
only specify certain CSS selectors. E.g. _hover would always trigger, when
the html element is hovered - that's mostly not intended.
{
text: {
default: 'gray.900',
_dark: 'gray.50'
}
}
Semantic Tokens can reference theme tokens like gray.900 and allow plain CSS
values like e.g. #F7FAFC.
import { ChakraProvider, extendTheme } from '@chakra-ui/react';
const customTheme = extendTheme({
semanticTokens: {
colors: {
error: 'red.500',
text: {
default: 'gray.900',
_dark: 'gray.50',
},
},
},
});
const App = () => (
<ChakraProvider theme={customTheme}>
<Text color='text'>
will be gray.900 in light mode and gray.50 in dark mode
</Text>
</ChakraProvider>
);
Theme Example
import { extendTheme } from '@chakra-ui/react';
const theme = extendTheme({
semanticTokens: {
colors: {
error: 'red.500',
success: 'green.500',
primary: {
default: 'red.500',
_dark: 'red.400',
},
secondary: {
default: 'red.800',
_dark: 'red.700',
},
},
},
});