# CSS theme variables - Configuration

A guide for configuring CSS theme variables in MaterialĀ UI.

## Customizing variable prefix To change the default variable prefix (`--mui`), provide a string to `cssVarPrefix` property, as shown below: ```js createTheme({ cssVariables: { cssVarPrefix: 'any' } }); // generated stylesheet: // --any-palette-primary-main: ...; ``` To remove the prefix, use an empty string as a value: ```js createTheme({ cssVariables: { cssVarPrefix: '' } }); // generated stylesheet: // --palette-primary-main: ...; ``` ## Toggling dark mode manually To toggle between modes manually, set the `colorSchemeSelector` with one of the following selectors: - `class`: adds a class to the `` element. ```js class createTheme({ colorSchemes: { light: true, dark: true }, cssVariables: { colorSchemeSelector: 'class' } }); // CSS Result .light { ... } .dark { ... } ``` - `data`: adds a data attribute to the `` element. ```js data createTheme({ colorSchemes: { light: true, dark: true }, cssVariables: { colorSchemeSelector: 'data' } }); // CSS Result [data-light] { ... } [data-dark] { ... } ``` - `string`: adds a custom selector to the `` element. ```js string // The value must start with dot (.) for class or square brackets ([]) for data createTheme({ colorSchemes: { light: true, dark: true }, cssVariables: { colorSchemeSelector: '.theme-%s' } }); // CSS Result .theme-light { ... } .theme-dark { ... } ``` Then, use `useColorScheme` hook to switch between modes: ```jsx import { useColorScheme } from '@mui/material/styles'; function ModeSwitcher() { const { mode, setMode } = useColorScheme(); if (!mode) { return null; } return ( ); } ``` :::success After React hydrates the tree, the mode is set to `system` to follow the user's preference. ::: ### Determining the system mode To determine if the system mode is `light` or `dark`, use the `systemMode` property: ```js const { mode, systemMode } = useColorScheme(); console.log(mode); // 'system' console.log(systemMode); // 'light' | 'dark' ``` However, if the mode is **not** `system`, the `systemMode` will be `undefined`. ```js const { mode, systemMode } = useColorScheme(); console.log(mode); // 'light' | 'dark' console.log(systemMode); // undefined ``` ### Preventing SSR flickering For SSR (server-side rendering) applications, MaterialĀ UI can not detected user-selected mode on the server, causing the screen to flicker from light to dark during the hydration phase on the client. To prevent the issue, you need to ensure that there is no usage of `theme.palette.mode === 'dark'` in your code base. If you have such a condition, replace it with the [`theme.applyStyles()` function](/material-ui/customization/dark-mode/#styling-in-dark-mode): ```diff import Card from '@mui/material/Card'; function App() { return ( ({ - backgroundColor: theme.palette.mode === 'dark' ? '#000' : '#fff', - '&:hover': { - backgroundColor: theme.palette.mode === 'dark' ? '#333' : '#f5f5f5', - }, - })} + sx={[ + { + backgroundColor: '#fff', + '&:hover': { + backgroundColor: '#f5f5f5', + }, + }, + (theme) => + theme.applyStyles('dark', { + backgroundColor: '#000', + '&:hover': { + backgroundColor: '#333', + }, + }), + ]} /> ); } ``` Next, if you have a custom selector that is **not** `media`, add the [`InitColorSchemeScript`](/material-ui/react-init-color-scheme-script/) component based on the framework that you are using: :::success The `attribute` has to be the same as the one you set in the `colorSchemeSelector` property: ```js createTheme({ cssVariables: { colorSchemeSelector: 'class' } }) ``` ::: ### Next.js App Router Add the following code to the [root layout](https://nextjs.org/docs/app/api-reference/file-conventions/layout#root-layouts) file: ```jsx title="app/layout.js" import InitColorSchemeScript from '@mui/material/InitColorSchemeScript'; export default function RootLayout(props) { return ( {/* must come before the
element */}
{children}
); } ``` :::warning If you don't add `suppressHydrationWarning` to your `` tag, you will see warnings about `"Extra attributes from the server"` because `InitColorSchemeScript` updates that element. ::: ### Next.js Pages Router Add the following code to the custom [`pages/_document.js`](https://nextjs.org/docs/pages/building-your-application/routing/custom-document) file: ```jsx title="pages/_document.js" import Document, { Html, Head, Main, NextScript } from 'next/document'; import InitColorSchemeScript from '@mui/material/InitColorSchemeScript'; export default class MyDocument extends Document { render() { return ( ... {/* must come before the
element */}
); } } ``` ### Gatsby Place the script in your [`gatsby-ssr.js`](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/) file: ```jsx import * as React from 'react'; import InitColorSchemeScript from '@mui/material/InitColorSchemeScript'; export function onRenderBody({ setPreBodyComponents }) { setPreBodyComponents([]); } ``` ## Forcing a specific color scheme To force a specific color scheme for some part of your application, set the selector to the component or HTML element directly. In the example below, all the components inside the `div` will always be dark: ```js class // if the selector is '.mode-%s'
{/* other components */}
``` ```js data-attribute // if the selector is '[data-mode-%s]'
{/* other components */}
```
## Disabling CSS color scheme By default, `createTheme()` attaches a [CSS `color-scheme` property](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/color-scheme) based on the palette mode. You can disable this by setting `disableCssColorScheme` to `true`: ```js createTheme({ cssVariables: { disableCssColorScheme: true }, }); ``` The generated CSS will not include the `color-scheme` property: ```diff @media (prefers-color-scheme: dark) { :root { - color-scheme: dark; --mui-palette-primary-main: #90caf9; ... } } ``` ## Instant transition between color schemes To disable CSS transitions when switching between modes, apply the `disableTransitionOnChange` prop: ```js ``` {{"demo": "DisableTransitionOnChange.js"}} ## Force theme recalculation between modes By default, the `ThemeProvider` does not re-render when switching between light and dark modes when `cssVariables: true` is set in the theme. If you want to opt-out from this behavior, use the `forceThemeRerender` prop in the ThemeProvider: ```js ```