UNPKG

@mui/material

Version:

Material UI is an open-source React component library that implements Google's Material Design. It's comprehensive and can be used in production out of the box.

1,081 lines (910 loc) • 32.6 kB
# Palette The palette enables you to modify the color of the components to suit your brand. ## Color tokens Palette colors are represented by four tokens: - `main`: The main shade of the color - `light`: A lighter shade of `main` - `dark`: A darker shade of `main` - `contrastText`: Text color, intended to contrast with `main` Here's how Material UI's default theme defines the primary color tokens: ```js const primary = { main: '#1976d2', light: '#42a5f5', dark: '#1565c0', contrastText: '#fff', }; ``` See the [Color](/material-ui/customization/color/) documentation for details on the Material Design color system. ## Default colors The theme exposes the following default palette colors (accessible under `theme.palette.*`): - `primary` - for primary interface elements. - `secondary` - for secondary interface elements. - `error` - for elements that the user should be made aware of. - `warning` - for potentially dangerous actions or important messages. - `info` - for highlighting neutral information. - `success` - for indicating the successful completion of an action that the user triggered. See Material Design's [Color System](https://m2.material.io/design/color/the-color-system.html) for details on color usage and guidelines. ### Values You can explore the default palette values using [the theme explorer](/material-ui/customization/default-theme/?expand-path=$.palette), or by opening the dev tools console on this page (`window.theme.palette`). ```jsx import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; import { useTheme, rgbToHex, styled } from '@mui/material/styles'; const Group = styled(Typography)(({ theme }) => ({ marginTop: theme.spacing(3), })); const Color = styled(Grid)(({ theme }) => ({ display: 'flex', alignItems: 'center', '& div:first-of-type': { width: theme.spacing(6), height: theme.spacing(6), marginRight: theme.spacing(1), borderRadius: theme.shape.borderRadius, boxShadow: 'inset 0 2px 4px 0 rgba(0, 0, 0, .06)', }, })); export default function Intentions() { const theme = useTheme(); const item = (color, name) => ( <Color size={{ xs: 12, sm: 6, md: 4 }}> <div style={{ backgroundColor: color }} /> <div> <Typography variant="body2">{name}</Typography> <Typography variant="body2" sx={{ color: 'text.secondary' }}> {rgbToHex(color)} </Typography> </div> </Color> ); return ( <Box sx={{ width: '100%' }}> <Group gutterBottom>Primary</Group> <Grid container spacing={2}> {item(theme.palette.primary.light, 'palette.primary.light')} {item(theme.palette.primary.main, 'palette.primary.main')} {item(theme.palette.primary.dark, 'palette.primary.dark')} </Grid> <Group gutterBottom>Secondary</Group> <Grid container spacing={2}> {item(theme.palette.secondary.light, 'palette.secondary.light')} {item(theme.palette.secondary.main, 'palette.secondary.main')} {item(theme.palette.secondary.dark, 'palette.secondary.dark')} </Grid> <Group gutterBottom>Error</Group> <Grid container spacing={2}> {item(theme.palette.error.light, 'palette.error.light')} {item(theme.palette.error.main, 'palette.error.main')} {item(theme.palette.error.dark, 'palette.error.dark')} </Grid> <Group gutterBottom>Warning</Group> <Grid container spacing={2}> {item(theme.palette.warning.light, 'palette.warning.light')} {item(theme.palette.warning.main, 'palette.warning.main')} {item(theme.palette.warning.dark, 'palette.warning.dark')} </Grid> <Group gutterBottom>Info</Group> <Grid container spacing={2}> {item(theme.palette.info.light, 'palette.info.light')} {item(theme.palette.info.main, 'palette.info.main')} {item(theme.palette.info.dark, 'palette.info.dark')} </Grid> <Group gutterBottom>Success</Group> <Grid container spacing={2}> {item(theme.palette.success.light, 'palette.success.light')} {item(theme.palette.success.main, 'palette.success.main')} {item(theme.palette.success.dark, 'palette.success.dark')} </Grid> </Box> ); } ``` The default palette uses the shades prefixed with `A` (`A200`, etc.) for the secondary palette color, and the un-prefixed shades for the other palette colors. ### Customization You may override the default palette values by including a palette object as part of your theme. If any of the: - [`.palette.primary`](/material-ui/customization/default-theme/?expand-path=$.palette.primary) - [`.palette.secondary`](/material-ui/customization/default-theme/?expand-path=$.palette.secondary) - [`.palette.error`](/material-ui/customization/default-theme/?expand-path=$.palette.error) - [`.palette.warning`](/material-ui/customization/default-theme/?expand-path=$.palette.warning) - [`.palette.info`](/material-ui/customization/default-theme/?expand-path=$.palette.info) - [`.palette.success`](/material-ui/customization/default-theme/?expand-path=$.palette.success) palette color objects are provided, they will replace the default ones. This can be achieved by either using a color object or by providing the colors directly: #### Using a color object The most direct way to customize a palette color is to import and apply one or more [color objects](/material-ui/customization/color/#2014-material-design-color-palettes), as shown below: ```tsx import { createTheme, ThemeProvider } from '@mui/material/styles'; import { lime, purple } from '@mui/material/colors'; import Button from '@mui/material/Button'; const theme = createTheme({ palette: { primary: lime, secondary: purple, }, }); export default function UsingColorObject() { return ( <ThemeProvider theme={theme}> <Button variant="contained">Primary</Button> <Button variant="contained" color="secondary" sx={{ ml: 2 }}> Secondary </Button> </ThemeProvider> ); } ``` #### Providing the colors directly To modify each color directly, provide an object with one or more of the color tokens. Only the `main` token is required; `light`, `dark`, and `contrastText` are optional, and if not provided, then their values are calculated automatically: ```js import { createTheme } from '@mui/material/styles'; const theme = createTheme({ palette: { primary: { main: '#FF5733', // light: will be calculated from palette.primary.main, // dark: will be calculated from palette.primary.main, // contrastText: will be calculated to contrast with palette.primary.main }, secondary: { main: '#E0C2FF', light: '#F5EBFF', // dark: will be calculated from palette.secondary.main, contrastText: '#47008F', }, }, }); ``` ```tsx import { createTheme, ThemeProvider } from '@mui/material/styles'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import { unstable_capitalize as capitalize } from '@mui/utils'; import Typography from '@mui/material/Typography'; const theme = createTheme({ palette: { primary: { main: '#FF5733', // light: will be calculated from palette.primary.main, // dark: will be calculated from palette.primary.main, // contrastText: will be calculated to contrast with palette.primary.main }, secondary: { main: '#E0C2FF', light: '#F5EBFF', // dark: will be calculated from palette.secondary.main, contrastText: '#47008F', }, }, }); function ColorShowcase({ color }: { color: 'primary' | 'secondary' }) { return ( <Stack sx={{ gap: 2, alignItems: 'center' }}> <Button variant="contained" color={color}> {capitalize(color)} </Button> <Stack direction="row" sx={{ gap: 1 }}> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">light</Typography> <Box sx={{ bgcolor: `${color}.light`, width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">main</Typography> <Box sx={{ bgcolor: `${color}.main`, width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">dark</Typography> <Box sx={{ bgcolor: `${color}.dark`, width: 40, height: 20 }} /> </Stack> </Stack> </Stack> ); } export default function ManuallyProvidePaletteColor() { return ( <ThemeProvider theme={theme}> <Stack direction="row" sx={{ gap: 8 }}> <ColorShowcase color="primary" /> <ColorShowcase color="secondary" /> </Stack> </ThemeProvider> ); } ``` ### Contrast threshold The `contrastText` token is calculated using the `contrastThreshold` value, to maximize the contrast between the background and the text. A higher contrast threshold value increases the point at which a background color is considered light, and thus given a dark `contrastText`. Note that the contrast threshold follows a non-linear curve, and defaults to a value of 3 which indicates a minimum contrast ratio of 3:1. ```tsx import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles'; import Button from '@mui/material/Button'; import { Stack } from '@mui/system'; const defaultContrastThresholdTheme = createTheme({}); const highContrastThresholdTheme = createTheme({ palette: { contrastThreshold: 4.5, }, }); function ContrastShowcase(props: { title: string }) { const { title } = props; const theme = useTheme(); return ( <Stack sx={{ gap: 1, alignItems: 'center' }}> <span> <b>{title}</b> </span> <span>{theme.palette.contrastThreshold}:1</span> <Stack direction="row" sx={{ gap: 1 }}> <Button variant="contained" color="warning"> Warning </Button> </Stack> </Stack> ); } export default function ContrastThreshold() { return ( <Stack direction="row" sx={{ gap: 4 }}> <ThemeProvider theme={defaultContrastThresholdTheme}> <ContrastShowcase title="Default contrast threshold" /> </ThemeProvider> <ThemeProvider theme={highContrastThresholdTheme}> <ContrastShowcase title="Higher contrast threshold" /> </ThemeProvider> </Stack> ); } ``` ### Tonal offset The `light` and `dark` tokens are calculated using the `tonalOffset` value, to shift the `main` color's luminance. A higher tonal offset value will make `light` tokens lighter, and `dark` tokens darker. :::warning This only applies when working with custom colors—it won't have any effect on the [default values](#default-colors). ::: For example, the tonal offset default value `0.2` shifts the luminance by approximately two indexes, so if the `main` token is `blue[500]`, then the `light` token would be `blue[300]` and `dark` would be `blue[700]`. The tonal offset value can be either a number between 0 and 1 (which would apply to both `light` and `dark` tokens) or an object with `light` and `dark` keys specified: ```tsx import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles'; import { blue } from '@mui/material/colors'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; const defaultTonalOffsetTheme = createTheme({ palette: { primary: { main: blue[500], }, }, }); const higherTonalOffsetTheme = createTheme({ palette: { primary: { main: blue[500], }, tonalOffset: 0.5, }, }); const asymmetricTonalOffsetTheme = createTheme({ palette: { primary: { main: blue[500], }, tonalOffset: { light: 0.1, dark: 0.9, }, }, }); function ColorShowcase({ title, color }: { title: string; color: string }) { const { palette: { tonalOffset }, } = useTheme(); let caption; if (typeof tonalOffset === 'number') { caption = tonalOffset; } else { caption = `{ light: ${tonalOffset.light}, dark: ${tonalOffset.dark} }`; } return ( <Stack sx={{ gap: 1, alignItems: 'center' }}> <span> <b>{title}</b> </span> <span>{caption}</span> <Stack direction="row" sx={{ gap: 1 }}> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">light</Typography> <Box sx={{ bgcolor: `${color}.light`, width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">main</Typography> <Box sx={{ bgcolor: `${color}.main`, width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">dark</Typography> <Box sx={{ bgcolor: `${color}.dark`, width: 40, height: 20 }} /> </Stack> </Stack> </Stack> ); } export default function TonalOffset() { return ( <Stack direction={{ xs: 'column', sm: 'row' }} sx={{ gap: 8 }}> <ThemeProvider theme={defaultTonalOffsetTheme}> <ColorShowcase title="Default tonal offset" color="primary" /> </ThemeProvider> <ThemeProvider theme={higherTonalOffsetTheme}> <ColorShowcase title="Higher tonal offset" color="primary" /> </ThemeProvider> <ThemeProvider theme={asymmetricTonalOffsetTheme}> <ColorShowcase title="Asymmetric tonal offset" color="primary" /> </ThemeProvider> </Stack> ); } ``` ## Custom colors :::warning Unlike [default colors](#default-colors), tokens for custom colors are _not_ automatically calculated. ::: To add custom colors, you must either provide the tokens manually, or generate them using the `augmentColor` utility: ### Provide tokens manually The most straightforward approach is to define all tokens—`main`, `light`, `dark`, and `contrastText`—manually: ```jsx import { createTheme } from '@mui/material/styles'; const theme = createTheme({ palette: { ochre: { main: '#E3D026', light: '#E9DB5D', dark: '#A29415', contrastText: '#242105', }, }, }); ``` ```tsx import { createTheme, ThemeProvider } from '@mui/material/styles'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; // Augment the palette to include an ochre color declare module '@mui/material/styles' { interface Palette { ochre: Palette['primary']; } interface PaletteOptions { ochre?: PaletteOptions['primary']; } } // Update the Button's color options to include an ochre option declare module '@mui/material/Button' { interface ButtonPropsColorOverrides { ochre: true; } } const theme = createTheme({ palette: { ochre: { main: '#E3D026', light: '#E9DB5D', dark: '#A29415', contrastText: '#242105', }, }, }); export default function ManuallyProvideCustomColor() { return ( <ThemeProvider theme={theme}> <Stack sx={{ gap: 2, alignItems: 'center' }}> <Button variant="contained" color="ochre"> Ochre </Button> <Stack direction="row" sx={{ gap: 1 }}> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">light</Typography> <Box sx={{ bgcolor: 'ochre.light', width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">main</Typography> <Box sx={{ bgcolor: 'ochre.main', width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">dark</Typography> <Box sx={{ bgcolor: 'ochre.dark', width: 40, height: 20 }} /> </Stack> </Stack> </Stack> </ThemeProvider> ); } ``` :::info The supported color formats are `hex`, `rgb`, and `hsl`. If you want to use other formats, such as `oklch`, you need to enable the [native color](/material-ui/customization/css-theme-variables/native-color/) feature. ::: <!-- #target-branch-reference --> If you need to manipulate colors, `@mui/material/styles` provides [a set of utilities](https://github.com/mui/material-ui/blob/v9.x/packages/mui-material/src/styles/index.d.ts#L52-L67) to help with this. The following example uses the `alpha()` and `getContrastRatio()` utilities to define tokens using opacity: ```jsx import { createTheme, alpha, getContrastRatio } from '@mui/material/styles'; const violetBase = '#7F00FF'; const violetMain = alpha(violetBase, 0.7); const theme = createTheme({ palette: { violet: { main: violetMain, light: alpha(violetBase, 0.5), dark: alpha(violetBase, 0.9), contrastText: getContrastRatio(violetMain, '#fff') > 4.5 ? '#fff' : '#111', }, }, }); ``` ```tsx import { createTheme, ThemeProvider, alpha, getContrastRatio, } from '@mui/material/styles'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; // Augment the palette to include a violet color declare module '@mui/material/styles' { interface Palette { violet: Palette['primary']; } interface PaletteOptions { violet?: PaletteOptions['primary']; } } // Update the Button's color options to include a violet option declare module '@mui/material/Button' { interface ButtonPropsColorOverrides { violet: true; } } const violetBase = '#7F00FF'; const violetMain = alpha(violetBase, 0.7); const theme = createTheme({ palette: { violet: { main: violetMain, light: alpha(violetBase, 0.5), dark: alpha(violetBase, 0.9), contrastText: getContrastRatio(violetMain, '#fff') > 4.5 ? '#fff' : '#111', }, }, }); export default function UsingStylesUtils() { return ( <ThemeProvider theme={theme}> <Stack sx={{ gap: 2, alignItems: 'center' }}> <Button variant="contained" color="violet"> Violet </Button> <Stack direction="row" sx={{ gap: 1 }}> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">light</Typography> <Box sx={{ bgcolor: 'violet.light', width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">main</Typography> <Box sx={{ bgcolor: 'violet.main', width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">dark</Typography> <Box sx={{ bgcolor: 'violet.dark', width: 40, height: 20 }} /> </Stack> </Stack> </Stack> </ThemeProvider> ); } ``` ### Generate tokens using augmentColor utility Alternatively, you can generate the `light`, `dark` and `contrastText` tokens using the palette's `augmentColor` utility, which is the same function used for the default palette colors. This requires creating the theme in two steps and providing the `main` token on which the other will be based on: ```jsx import { createTheme } from '@mui/material/styles'; let theme = createTheme({ // Theme customization goes here as usual, including tonalOffset and/or // contrastThreshold as the augmentColor() function relies on these }); theme = createTheme(theme, { // Custom colors created with augmentColor go here palette: { salmon: theme.palette.augmentColor({ color: { main: '#FF5733', }, name: 'salmon', }), }, }); ``` ```tsx import { createTheme, ThemeProvider } from '@mui/material/styles'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; // Augment the palette to include a salmon color declare module '@mui/material/styles' { interface Palette { salmon: Palette['primary']; } interface PaletteOptions { salmon?: PaletteOptions['primary']; } } // Update the Button's color options to include a salmon option declare module '@mui/material/Button' { interface ButtonPropsColorOverrides { salmon: true; } } let theme = createTheme({ // Theme customization goes here as usual, including tonalOffset and/or // contrastThreshold as the augmentColor() function relies on these }); theme = createTheme(theme, { // Custom colors created with augmentColor go here palette: { salmon: theme.palette.augmentColor({ color: { main: '#FF5733', }, name: 'salmon', }), }, }); export default function UsingAugmentColor() { return ( <ThemeProvider theme={theme}> <Stack sx={{ gap: 2, alignItems: 'center' }}> <Button variant="contained" color="salmon"> Salmon </Button> <Stack direction="row" sx={{ gap: 1 }}> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">light</Typography> <Box sx={{ bgcolor: 'salmon.light', width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">main</Typography> <Box sx={{ bgcolor: 'salmon.main', width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">dark</Typography> <Box sx={{ bgcolor: 'salmon.dark', width: 40, height: 20 }} /> </Stack> </Stack> </Stack> </ThemeProvider> ); } ``` The [contrast threshold](#contrast-threshold) and [tonal offset](#tonal-offset) values will apply for the colors defined using this utility. ### Using in components After adding a custom color, you will be able to use it in components just like you do with default palette colors: ```js <Button color="custom"> ``` ### TypeScript If you're using TypeScript, then you need to use [module augmentation](/material-ui/guides/typescript/#customization-of-theme) for custom colors. To add a custom color to the palette, you must add it to the `Palette` and `PaletteOptions` interfaces: <!-- tested with packages/mui-material/test/typescript/augmentation/paletteColors.spec.ts --> ```ts declare module '@mui/material/styles' { interface Palette { custom: Palette['primary']; } interface PaletteOptions { custom?: PaletteOptions['primary']; } } ``` To use a custom color for the `color` prop of a component, you must add it to the component's `PropsColorOverrides` interface. The example below shows how to do this with a Button component: <!-- tested with packages/mui-material/test/typescript/augmentation/paletteColors.spec.ts --> ```ts declare module '@mui/material/Button' { interface ButtonPropsColorOverrides { custom: true; } } ``` ## Adding color tokens To add a new [color token](#color-tokens), include it in the color's object as follows: ```jsx import { createTheme } from '@mui/material/styles'; import { blue } from '@mui/material/colors'; const theme = createTheme({ palette: { primary: { light: blue[300], main: blue[500], dark: blue[700], darker: blue[900], }, }, }); ``` ```tsx import { createTheme, ThemeProvider } from '@mui/material/styles'; import { blue } from '@mui/material/colors'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; declare module '@mui/material/styles' { interface PaletteColor { darker?: string; } interface SimplePaletteColorOptions { darker?: string; } } const theme = createTheme({ palette: { primary: { light: blue[300], main: blue[500], dark: blue[700], darker: blue[900], }, }, }); export default function AddingColorTokens() { return ( <ThemeProvider theme={theme}> <Stack direction="row" sx={{ gap: 1 }}> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">light</Typography> <Box sx={{ bgcolor: `primary.light`, width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">main</Typography> <Box sx={{ bgcolor: `primary.main`, width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">dark</Typography> <Box sx={{ bgcolor: `primary.dark`, width: 40, height: 20 }} /> </Stack> <Stack sx={{ alignItems: 'center' }}> <Typography variant="body2">darker</Typography> <Box sx={{ bgcolor: `primary.darker`, width: 40, height: 20 }} /> </Stack> </Stack> </ThemeProvider> ); } ``` ### TypeScript If you're using TypeScript, then you'll need to use [module augmentation](/material-ui/guides/typescript/#customization-of-theme) to add the new color token to the `PaletteColor` and `SimplePaletteColorOptions` interfaces as follows: <!-- tested with packages/mui-material/test/typescript/augmentation/paletteColors.spec.ts --> ```ts declare module '@mui/material/styles' { interface PaletteColor { darker?: string; } interface SimplePaletteColorOptions { darker?: string; } } ``` ## Non-palette colors To learn how to add colors outside of `theme.palette`, see [Theming—Custom variables](/material-ui/customization/theming/#custom-variables). ## Accessibility To meet the minimum contrast of at least 4.5:1 as defined in [WCAG 2.2 Success Criterion 1.4.3](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html), create a custom theme with a [contrast threshold](#contrast-threshold) value of 4.5 as follows: ```js import { createTheme } from '@mui/material/styles'; const theme = createTheme({ palette: { contrastThreshold: 4.5, }, }); ``` :::warning The `contrastThreshold` parameter can produce counterproductive results.\ Please verify that the [APCA](https://contrast.tools/?tab=apca) color contrast is improved (WCAG 3 [will use](https://typefully.com/DanHollick/wcag-3-and-apca-sle13GMW2Brp) this new algorithm). ::: ### Windows High Contrast mode To improve component visibility in Windows High Contrast mode (also known as [Forced Colors](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors)), use the `enhanceHighContrast` theme enhancer, starting from v9.1.0. It accepts a fully-created theme and returns an enhanced version of it with `@media (forced-colors: active)` overrides applied to the affected components. ```js import { createTheme, enhanceHighContrast } from '@mui/material/styles'; const theme = enhanceHighContrast(createTheme()); ``` By default, it uses the [CSS system color keywords](https://www.w3.org/TR/css-color-4/#css-system-colors) (`Highlight`, `HighlightText`, `ButtonBorder`, etc.). You can override individual tokens with other [system colors](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/system-color) to match your brand or design requirements. When overriding paired tokens, choose values that the browser guarantees to contrast with each other — for example `SelectedItem` is always paired with `SelectedItemText`, and `Highlight` with `HighlightText`: ```js import { createTheme, enhanceHighContrast } from '@mui/material/styles'; const theme = enhanceHighContrast(createTheme(), { // Use the system's selection colors for active or toggled controls. activeBackground: 'SelectedItem', activeText: 'SelectedItemText', }); ``` The following tokens are available, showing how your browser resolves each system color keyword in the current environment: ```jsx import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import { styled } from '@mui/material/styles'; // TODO: Ideally this should be generated from the HighContrastTokens TS interface // rather than maintained manually, but auto-extraction would lose descriptions and // default values. A solution that exports token metadata from the interface is needed. const tokens = [ { token: 'disabled', color: 'GrayText', description: 'Color for disabled elements', }, { token: 'error', color: 'ActiveText', description: 'Color for error states' }, { token: 'selectedBackground', color: 'SelectedItem', description: 'Background color for selected items', }, { token: 'selectedText', color: 'SelectedItemText', description: 'Text color on selected items', }, { token: 'activeBackground', color: 'Highlight', description: 'Background color for active or toggled controls', }, { token: 'activeText', color: 'HighlightText', description: 'Text color on active or toggled controls', }, { token: 'buttonBorder', color: 'ButtonBorder', description: 'Border color for interactive controls', }, { token: 'buttonText', color: 'ButtonText', description: 'Text and icon color on buttons', }, { token: 'canvas', color: 'Canvas', description: 'Background color for the page or canvas', }, ]; const Table = styled('table')(({ theme }) => ({ width: '100%', borderCollapse: 'collapse', ...theme.typography.body2, })); const Th = styled('th')(({ theme }) => ({ textAlign: 'left', padding: theme.spacing(1, 2), borderBottom: `2px solid ${theme.palette.divider}`, whiteSpace: 'nowrap', })); const Td = styled('td')(({ theme }) => ({ padding: theme.spacing(1, 2), borderBottom: `1px solid ${theme.palette.divider}`, verticalAlign: 'middle', })); const ColorSwatch = styled('div')(({ theme }) => ({ display: 'inline-block', width: theme.spacing(3), height: theme.spacing(3), marginRight: theme.spacing(1), borderRadius: theme.shape.borderRadius, outline: '1px solid ButtonBorder', verticalAlign: 'middle', })); export default function HighContrastTokens() { return ( <Box sx={{ width: '100%', overflowX: 'auto' }}> <Table> <thead> <tr> <Th>Token</Th> <Th>Default</Th> <Th>Description</Th> </tr> </thead> <tbody> {tokens.map(({ token, color, description }) => ( <tr key={token}> <Td> <code>{token}</code> </Td> <Td> <ColorSwatch style={{ backgroundColor: color }} /> <Typography component="code" variant="body2"> {color} </Typography> </Td> <Td sx={{ color: 'text.secondary' }}>{description}</Td> </tr> ))} </tbody> </Table> </Box> ); } ``` ## Picking colors Need inspiration? The Material Design team has built an [palette configuration tool](/material-ui/customization/color/#picking-colors) to help you. ## Color schemes To add both built-in light and dark color schemes without creating separate themes, use the `colorSchemes: { light: true, dark: true }`. This generates the default tokens for both color schemes: ```js import { createTheme } from '@mui/material/styles'; const theme = createTheme({ colorSchemes: { light: true, dark: true, }, }); ``` To override the default tokens for each color scheme, use the same [palette object](#customization) as shown below: ```js const theme = createTheme({ colorSchemes: { light: { palette: { primary: { main: '#FF5733', }, // ...other tokens }, }, dark: { palette: { primary: { main: '#E0C2FF', }, // ...other tokens }, }, }, }); ``` :::warning The `colorSchemes` API is an enhanced version of the `palette` API, and is the preferred API for this purpose starting from Material UI v6. If you provide both `colorSchemes` and `palette`, the latter will override any styles defined in the former. ```js const theme = createTheme({ palette: { primary: { main: '...', }, }, colorSchemes: { light: { // This will be replaced by the palette defined above palette: { primary: { main: '...', }, }, }, dark: { ... }, }, }); ``` ::: ## Dark mode For details of how you can set up a dark mode for your theme, head to the [dark mode guide](/material-ui/customization/dark-mode/).