CSS theme variables - Usage
Learn how to adopt CSS theme variables.
Getting started
To use CSS theme variables, create a theme with cssVariables: true
and wrap your app with ThemeProvider
.
After rendering, you'll see CSS variables in the :root
stylesheet of your HTML document.
By default, these variables are flattened and prefixed with --mui
:
import { ThemeProvider, createTheme } from '@mui/material/styles';
const theme = createTheme({ cssVariables: true });
function App() {
return <ThemeProvider theme={theme}>{/* ...your app */}</ThemeProvider>;
}
Light and dark modes
When the built-in dark color scheme and cssVariables
are enabled, both light and dark CSS variables are generated with the default CSS media prefers-color-scheme
method.
This method works with server-side rendering without extra configuration. However, users won't be able to toggle between modes because the styles are based on the browser media.
If you want to be able to manually toggle modes, see the guide to toggling dark mode manually.
Applying dark styles
To customize styles for dark mode, use theme.applyStyles()
function.
This utility function will return the right selector.
The example below shows how to customize the Card component for dark mode:
import Card from '@mui/material/Card';
<Card
sx={(theme) => ({
backgroundColor: theme.vars.palette.background.default,
...theme.applyStyles('dark', {
boxShadow: 'none', // remove the box shadow in dark mode
}),
})}
/>;
Using theme variables
When the CSS variables feature is enabled, the vars
node is added to the theme.
This vars
object mirrors the structure of a serializable theme, with each value corresponding to a CSS variable.
theme.vars
(recommended): an object that refers to the CSS theme variables.const Button = styled('button')(({ theme }) => ({ backgroundColor: theme.vars.palette.primary.main, // var(--mui-palette-primary-main) color: theme.vars.palette.primary.contrastText, // var(--mui-palette-primary-contrastText) }));
For TypeScript, the typings are not enabled by default. Follow the TypeScript setup to enable the typings.
Native CSS: if you can't access the theme object, for example in a pure CSS file, you can use
var()
directly:/* external-scope.css */ .external-section { background-color: var(--mui-palette-grey-50); }
Color channel tokens
Enabling cssVariables
automatically generates channel tokens which are used to create translucent colors.
These tokens consist of color space channels without the alpha component, separated by spaces.
The colors are suffixed with Channel
—for example:
const theme = createTheme({ cssVariables: true });
console.log(theme.palette.primary.mainChannel); // '25 118 210'
// This token is generated from `theme.colorSchemes.light.palette.primary.main`.
You can use the channel tokens to create a translucent color like this:
const theme = createTheme({
cssVariables: true,
components: {
MuiChip: {
styleOverrides: {
root: ({ theme }) => ({
variants: [
{
props: { variant: 'outlined', color: 'primary' },
style: {
backgroundColor: `rgba(${theme.vars.palette.primary.mainChannel} / 0.12)`,
},
},
],
}),
},
},
},
});
Adding new theme tokens
You can add other key-value pairs to the theme input which will be generated as a part of the CSS theme variables:
const theme = createTheme({
cssVariables: true,
colorSchemes: {
light: {
palette: {
// The best part is that you can refer to the variables wherever you like 🤩
gradient:
'linear-gradient(to left, var(--mui-palette-primary-main), var(--mui-palette-primary-dark))',
border: {
subtle: 'var(--mui-palette-neutral-200)',
},
},
},
dark: {
palette: {
gradient:
'linear-gradient(to left, var(--mui-palette-primary-light), var(--mui-palette-primary-main))',
border: {
subtle: 'var(--mui-palette-neutral-600)',
},
},
},
},
});
function App() {
return <ThemeProvider theme={theme}>...</ThemeProvider>;
}
Then, you can access those variables from the theme.vars
object:
const Divider = styled('hr')(({ theme }) => ({
height: 1,
border: '1px solid',
borderColor: theme.vars.palette.border.subtle,
backgroundColor: theme.vars.palette.gradient,
}));
Or use var()
to refer to the CSS variable directly:
/* global.css */
.external-section {
background-color: var(--mui-palette-gradient);
}
For TypeScript, you need to augment the palette interfaces.
TypeScript
The theme variables type is not enabled by default. You need to import the module augmentation to enable the typings:
// The import can be in any file that is included in your `tsconfig.json`
import type {} from '@mui/material/themeCssVarsAugmentation';
import { styled } from '@mui/material/styles';
const StyledComponent = styled('button')(({ theme }) => ({
// ✅ typed-safe
color: theme.vars.palette.primary.main,
}));
Palette interfaces
To add new tokens to the theme palette, you need to augment the PaletteOptions
and Palette
interfaces:
declare module '@mui/material/styles' {
interface PaletteOptions {
gradient: string;
border: {
subtle: string;
};
}
interface Palette {
gradient: string;
border: {
subtle: string;
};
}
}
Next steps
If you need to support system preference and manual selection, check out the advanced configuration