# Source: https://mui.com/material-ui/customization/theming.md

# Theming

Customize Material UI with your theme. You can change the colors, the typography and much more.

The theme specifies the color of the components, darkness of the surfaces, level of shadow, appropriate opacity of ink elements, etc.

Themes let you apply a consistent tone to your app. It allows you to **customize all design aspects** of your project in order to meet the specific needs of your business or brand.

To promote greater consistency between apps, light and dark theme types are available to choose from. By default, components use the light theme type.

## Theme provider

Material UI components adhere to the library's default theme out of the box.
Use `ThemeProvider` to inject a custom theme into your application.

`ThemeProvider` relies on the [context feature of React](https://react.dev/learn/passing-data-deeply-with-context) to pass the theme down to the components, so you need to make sure that `ThemeProvider` is a parent of the components you are trying to customize.
You can learn more about this in [the API section](#themeprovider).

## Theme configuration variables

Changing the theme configuration variables is the most effective way to match Material UI to your needs.
The following sections cover the most important theme variables:

- [`.palette`](/material-ui/customization/palette/)
- [`.typography`](/material-ui/customization/typography/)
- [`.spacing`](/material-ui/customization/spacing/)
- [`.breakpoints`](/material-ui/customization/breakpoints/)
- [`.zIndex`](/material-ui/customization/z-index/)
- [`.transitions`](/material-ui/customization/transitions/)
- [`.components`](/material-ui/customization/theme-components/)

You can check out the [default theme section](/material-ui/customization/default-theme/) to view the default theme in full.

### Custom variables

When using Material UI's theme with [MUI System](/system/getting-started/) or [any other styling solution](/material-ui/integrations/interoperability/), it can be convenient to add additional variables to the theme so you can use them everywhere.
For instance:

```jsx
const theme = createTheme({
  status: {
    danger: orange[500],
  },
});
```

:::warning
`vars` is an autogenerated field for [CSS theme variables](/material-ui/customization/css-theme-variables/overview/).
It will throw an error if you try to pass a value to it:

```jsx
createTheme({
  vars: { ... }, // ❌ error
})
```

:::

### TypeScript

You have to use [module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) to add new variables to the `Theme` and `ThemeOptions`.

```tsx
declare module '@mui/material/styles' {
  interface Theme {
    status: {
      danger: string;
    };
  }
  // allow configuration using `createTheme()`
  interface ThemeOptions {
    status?: {
      danger?: string;
    };
  }
}
```

```tsx
import Checkbox from '@mui/material/Checkbox';
import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
import { orange } from '@mui/material/colors';

declare module '@mui/material/styles' {
  interface Theme {
    status: {
      danger: string;
    };
  }
  // allow configuration using `createTheme()`
  interface ThemeOptions {
    status?: {
      danger?: string;
    };
  }
}

const CustomCheckbox = styled(Checkbox)(({ theme }) => ({
  color: theme.status.danger,
  '&.Mui-checked': {
    color: theme.status.danger,
  },
}));

const theme = createTheme({
  status: {
    danger: orange[500],
  },
});

export default function CustomStyles() {
  return (
    <ThemeProvider theme={theme}>
      <CustomCheckbox defaultChecked />
    </ThemeProvider>
  );
}

```

To add extra variables to the `theme.palette`, see [palette customization](/material-ui/customization/palette/).

## Theme builder

<video autoPlay muted loop width="320">
  <source src="/static/studies.mp4" type="video/mp4" >
</video>

The community has built great tools to build a theme:

- [mui-theme-creator](https://zenoo.github.io/mui-theme-creator/): A tool to help design and customize themes for the Material UI component library. Includes basic site templates to show various components and how they are affected by the theme
- [Material palette generator](https://m2.material.io/inline-tools/color/): The Material palette generator can be used to generate a palette for any color you input.

## Accessing the theme in a component

You can access the theme variables inside your functional React components using the `useTheme` hook:

```jsx
import { useTheme } from '@mui/material/styles';

function DeepChild() {
  const theme = useTheme();
  return <span>{`spacing ${theme.spacing}`}</span>;
}
```

## Nesting the theme

[You can nest](https://v6.mui.com/system/styles/advanced/#theme-nesting) multiple theme providers.

```tsx
import { createTheme, ThemeProvider } from '@mui/material/styles';
import Checkbox from '@mui/material/Checkbox';
import { green, orange } from '@mui/material/colors';

const outerTheme = createTheme({
  palette: {
    primary: {
      main: orange[500],
    },
  },
});

const innerTheme = createTheme({
  palette: {
    primary: {
      main: green[500],
    },
  },
});

export default function ThemeNesting() {
  return (
    <ThemeProvider theme={outerTheme}>
      <Checkbox defaultChecked />
      <ThemeProvider theme={innerTheme}>
        <Checkbox defaultChecked />
      </ThemeProvider>
    </ThemeProvider>
  );
}

```

The inner theme will **override** the outer theme.
You can extend the outer theme by providing a function:

```tsx
import { createTheme, Theme, ThemeProvider } from '@mui/material/styles';
import Checkbox from '@mui/material/Checkbox';
import { green, orange } from '@mui/material/colors';

const outerTheme = createTheme({
  palette: {
    secondary: {
      main: orange[500],
    },
  },
});

export default function ThemeNestingExtend() {
  return (
    <ThemeProvider theme={outerTheme}>
      <Checkbox defaultChecked color="secondary" />
      <ThemeProvider
        theme={(theme: Theme) =>
          createTheme({
            ...theme,
            palette: {
              ...theme.palette,
              primary: {
                main: green[500],
              },
            },
          })
        }
      >
        <Checkbox defaultChecked />
        <Checkbox defaultChecked color="secondary" />
      </ThemeProvider>
    </ThemeProvider>
  );
}

```

## CSS theme variables

To generate CSS variables from the theme, set `cssVariables` to `true` in the theme configuration and pass it to the `ThemeProvider`:

```jsx
const theme = createTheme({
  cssVariables: true,
});

function App() {
  return <ThemeProvider theme={theme}>...</ThemeProvider>;
}
```

This generates a global stylesheet with the CSS theme variables:

```css
:root {
  --mui-palette-primary-main: #1976d2;
  /* ...other variables */
}
```

All components under the `ThemeProvider` will use those CSS theme variables instead of raw values.

```diff title="Button styles"
- color: #1976d2;
+ color: var(--mui-palette-primary-main);
```

To learn more about this feature, see the [CSS theme variables guide](/material-ui/customization/css-theme-variables/overview/).

## API

### `createTheme(options, ...args) => theme`

Generate a theme base on the options received. Then, pass it as a prop to [`ThemeProvider`](#themeprovider).

#### Arguments

1. `options` (_object_): Takes an incomplete theme object and adds the missing parts.
2. `...args` (_object[]_): Deep merge the arguments with the about to be returned theme.

:::warning
Only the first argument (`options`) is processed by the `createTheme()` function.
While passing multiple arguments currently works for backward compatibility, this behavior may be removed in future versions.
To ensure your code remains forward-compatible, you should manually deep merge the theme objects and pass the result as a single object to `createTheme()`.
:::

```js
import { deepmerge } from '@mui/utils';
import { createTheme } from '@mui/material/styles';

const theme = createTheme(deepmerge(options1, options2));
```

#### Returns

`theme` (_object_): A complete, ready-to-use theme object.

#### Examples

```js
import { createTheme } from '@mui/material/styles';
import { green, purple } from '@mui/material/colors';

const theme = createTheme({
  palette: {
    primary: {
      main: purple[500],
    },
    secondary: {
      main: green[500],
    },
  },
});
```

#### Theme composition: using theme options to define other options

When the value for a theme option is dependent on another theme option, you should compose the theme in steps.

```js
import { createTheme } from '@mui/material/styles';

let theme = createTheme({
  palette: {
    primary: {
      main: '#0052cc',
    },
    secondary: {
      main: '#edf2ff',
    },
  },
});

theme = createTheme(theme, {
  palette: {
    info: {
      main: theme.palette.secondary.main,
    },
  },
});
```

Think of creating a theme as a two-step composition process: first, you define the basic design options; then, you'll use these design options to compose other options.

**WARNING**: `theme.vars` is a private field used for CSS variables support. Please use another name for a custom object.

### Merging className and style props in defaultProps

By default, when a component has `defaultProps` defined in the theme, props passed to the component override the default props completely.

```jsx
import { createTheme } from '@mui/material/styles';

const theme = createTheme({
  components: {
    MuiButton: {
      defaultProps: {
        className: 'default-button-class',
        style: { marginTop: 8 },
      },
    },
  },
});

// className will be: "custom-button-class" (default ignored)
// style will be: { color: 'blue' } (default ignored)
<Button className="custom-button-class" style={{ color: 'blue' }}>
  Click me
</Button>;
```

You can change this behavior by configuring the theme to merge `className` and `style` props instead of replacing them.

To do this, set `theme.components.mergeClassNameAndStyle` to `true`:

```jsx
import { createTheme } from '@mui/material/styles';

const theme = createTheme({
  components: {
    mergeClassNameAndStyle: true,
    MuiButton: {
      defaultProps: {
        className: 'default-button-class',
        style: { marginTop: 8 },
      },
    },
  },
});
```

Here's what the example above looks like with this configuration:

```jsx
// className will be: "default-button-class custom-button-class"
// style will be: { marginTop: 8, color: 'blue' }
<Button className="custom-button-class" style={{ color: 'blue' }}>
  Click me
</Button>
```

### `responsiveFontSizes(theme, options) => theme`

Generate responsive typography settings based on the options received.

#### Arguments

1. `theme` (_object_): The theme object to enhance.
2. `options` (_object_ [optional]):

- `breakpoints` (_array\<string\>_ [optional]): Default to `['sm', 'md', 'lg']`. Array of [breakpoints](/material-ui/customization/breakpoints/) (identifiers).
- `disableAlign` (_bool_ [optional]): Default to `false`. Whether font sizes change slightly so line
  heights are preserved and align to Material Design's 4px line height grid.
  This requires a unitless line height in the theme's styles.
- `factor` (_number_ [optional]): Default to `2`. This value determines the strength of font size resizing. The higher the value, the less difference there is between font sizes on small screens.
  The lower the value, the bigger font sizes for small screens. The value must be greater than 1.
- `variants` (_array\<string\>_ [optional]): Default to all. The typography variants to handle.

#### Returns

`theme` (_object_): The new theme with a responsive typography.

#### Examples

```js
import { createTheme, responsiveFontSizes } from '@mui/material/styles';

let theme = createTheme();
theme = responsiveFontSizes(theme);
```

### `unstable_createMuiStrictModeTheme(options, ...args) => theme`

**WARNING**: Do not use this method in production.

Generates a theme that reduces the amount of warnings inside [`React.StrictMode`](https://react.dev/reference/react/StrictMode) like `Warning: findDOMNode is deprecated in StrictMode`.

#### Requirements

Currently `unstable_createMuiStrictModeTheme` adds no additional requirements.

#### Arguments

1. `options` (_object_): Takes an incomplete theme object and adds the missing parts.
2. `...args` (_object[]_): Deep merge the arguments with the about to be returned theme.

#### Returns

`theme` (_object_): A complete, ready-to-use theme object.

#### Examples

```js
import { unstable_createMuiStrictModeTheme } from '@mui/material/styles';

const theme = unstable_createMuiStrictModeTheme();

function App() {
  return (
    <React.StrictMode>
      <ThemeProvider theme={theme}>
        <LandingPage />
      </ThemeProvider>
    </React.StrictMode>
  );
}
```

### `ThemeProvider`

This component takes a `theme` prop and applies it to the entire React tree that it is wrapping around.
It should preferably be used at **the root of your component tree**.

#### Props

| Name             | Type                                     | Description                                                                                                                                                                                               |
| :--------------- | :--------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| children&nbsp;\* | node                                     | Your component tree.                                                                                                                                                                                      |
| theme&nbsp;\*    | union:&nbsp;object&nbsp;&#124;&nbsp;func | A theme object, usually the result of [`createTheme()`](#createtheme-options-args-theme). The provided theme will be merged with the default theme. You can provide a function to extend the outer theme. |

#### Examples

```jsx
import * as React from 'react';
import { red } from '@mui/material/colors';
import { ThemeProvider, createTheme } from '@mui/material/styles';

const theme = createTheme({
  palette: {
    primary: {
      main: red[500],
    },
  },
});

function App() {
  return <ThemeProvider theme={theme}>...</ThemeProvider>;
}
```