Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
222 lines
8.0 KiB
Markdown
222 lines
8.0 KiB
Markdown
---
|
||
productId: material-ui
|
||
components: GlobalStyles
|
||
---
|
||
|
||
# How to customize
|
||
|
||
<p class="description">Learn how to customize Material UI components by taking advantage of different strategies for specific use cases.</p>
|
||
|
||
Material UI provides several different ways to customize a component's styles. Your specific context will determine which one is ideal. From narrowest to broadest use case, here are the options:
|
||
|
||
1. [One-off customization](#1-one-off-customization)
|
||
1. [Reusable component](#2-reusable-component)
|
||
1. [Global theme overrides](#3-global-theme-overrides)
|
||
1. [Global CSS override](#4-global-css-override)
|
||
|
||
## 1. One-off customization
|
||
|
||
To change the styles of _one single instance_ of a component, you can use one of the following options:
|
||
|
||
### The `sx` prop
|
||
|
||
The [`sx` prop](/system/getting-started/the-sx-prop/) is the best option for adding style overrides to a single instance of a component in most cases.
|
||
It can be used with all Material UI components.
|
||
|
||
{{"demo": "SxProp.js"}}
|
||
|
||
### Overriding nested component styles
|
||
|
||
To customize a specific part of a component, you can use the class name provided by Material UI inside the `sx` prop. As an example, let's say you want to change the `Slider` component's thumb from a circle to a square.
|
||
|
||
First, use your browser's dev tools to identify the class for the component slot you want to override.
|
||
|
||
The styles injected into the DOM by Material UI rely on class names that all [follow a standard pattern](https://v6.mui.com/system/styles/advanced/#class-names):
|
||
`[hash]-Mui[Component name]-[name of the slot]`.
|
||
|
||
In this case, the styles are applied with `.css-ae2u5c-MuiSlider-thumb` but you only really need to target the `.MuiSlider-thumb`, where `Slider` is the component and `thumb` is the slot. Use this class name to write a CSS selector within the `sx` prop (`& .MuiSlider-thumb`), and add your overrides.
|
||
|
||
<img src="/static/images/customization/dev-tools.png" alt="dev-tools" style="margin-bottom: 16px;" width="2400" height="800" />
|
||
|
||
{{"demo": "DevTools.js"}}
|
||
|
||
:::warning
|
||
These class names can't be used as CSS selectors because they are unstable.
|
||
:::
|
||
|
||
### Overriding styles with class names
|
||
|
||
If you want to override a component's styles using custom classes, you can use the `className` prop, available on each component.
|
||
To override the styles of a specific part of the component, use the global classes provided by Material UI, as described in the previous section **"Overriding nested component styles"** under the [`sx` prop section](#the-sx-prop).
|
||
|
||
Visit the [Style library interoperability](/material-ui/integrations/interoperability/) guide to find examples of this approach using different styling libraries.
|
||
|
||
### State classes
|
||
|
||
States like _hover_, _focus_, _disabled_ and _selected_, are styled with a higher CSS specificity. To customize them, you'll need to **increase specificity**.
|
||
|
||
Here is an example with the _disabled_ state and the `Button` component using a pseudo-class (`:disabled`):
|
||
|
||
```css
|
||
.Button {
|
||
color: black;
|
||
}
|
||
|
||
/* Increase the specificity */
|
||
.Button:disabled {
|
||
color: white;
|
||
}
|
||
```
|
||
|
||
```jsx
|
||
<Button disabled className="Button">
|
||
```
|
||
|
||
You can't always use a CSS pseudo-class, as the state doesn't exist in the web specification.
|
||
Let's take the `MenuItem` component and its _selected_ state as an example.
|
||
In this situation, you can use Material UI's **state classes**, which act just like CSS pseudo-classes.
|
||
Target the `.Mui-selected` global class name to customize the special state of the `MenuItem` component:
|
||
|
||
```css
|
||
.MenuItem {
|
||
color: black;
|
||
}
|
||
|
||
/* Increase the specificity */
|
||
.MenuItem.Mui-selected {
|
||
color: blue;
|
||
}
|
||
```
|
||
|
||
```jsx
|
||
<MenuItem selected className="MenuItem">
|
||
```
|
||
|
||
If you'd like to learn more about this topic, we recommend checking out [the MDN Web Docs on CSS Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascade/Specificity).
|
||
|
||
#### Why do I need to increase specificity to override one component state?
|
||
|
||
CSS pseudo-classes have a high level of specificity.
|
||
For consistency with native elements, Material UI's state classes have the same level of specificity as CSS pseudo-classes, making it possible to target an individual component's state.
|
||
|
||
#### What custom state classes are available in Material UI?
|
||
|
||
You can rely on the following [global class names](https://v6.mui.com/system/styles/advanced/#class-names) generated by Material UI:
|
||
|
||
| State | Global class name |
|
||
| :------------ | :------------------ |
|
||
| active | `.Mui-active` |
|
||
| checked | `.Mui-checked` |
|
||
| completed | `.Mui-completed` |
|
||
| disabled | `.Mui-disabled` |
|
||
| error | `.Mui-error` |
|
||
| expanded | `.Mui-expanded` |
|
||
| focus visible | `.Mui-focusVisible` |
|
||
| focused | `.Mui-focused` |
|
||
| readOnly | `.Mui-readOnly` |
|
||
| required | `.Mui-required` |
|
||
| selected | `.Mui-selected` |
|
||
|
||
:::error
|
||
Never apply styles directly to state class names. This will impact all components with unclear side-effects. Always target a state class together with a component.
|
||
:::
|
||
|
||
```css
|
||
/* ❌ NOT OK */
|
||
.Mui-error {
|
||
color: red;
|
||
}
|
||
|
||
/* ✅ OK */
|
||
.MuiOutlinedInput-root.Mui-error {
|
||
color: red;
|
||
}
|
||
```
|
||
|
||
## 2. Reusable component
|
||
|
||
To reuse the same overrides in different locations across your application, create a reusable component using the [`styled()`](/system/styled/) utility:
|
||
|
||
{{"demo": "StyledCustomization.js", "defaultCodeOpen": true}}
|
||
|
||
### Dynamic overrides
|
||
|
||
The `styled()` utility lets you add dynamic styles based on a component's props.
|
||
You can do this with **dynamic CSS** or **CSS variables**.
|
||
|
||
#### Dynamic CSS
|
||
|
||
:::warning
|
||
If you are using TypeScript, you will need to update the prop's types of the new component.
|
||
:::
|
||
|
||
{{"demo": "DynamicCSS.js", "defaultCodeOpen": false}}
|
||
|
||
```tsx
|
||
import * as React from 'react';
|
||
import { styled } from '@mui/material/styles';
|
||
import Slider, { SliderProps } from '@mui/material/Slider';
|
||
|
||
interface StyledSliderProps extends SliderProps {
|
||
success?: boolean;
|
||
}
|
||
|
||
const StyledSlider = styled(Slider, {
|
||
shouldForwardProp: (prop) => prop !== 'success',
|
||
})<StyledSliderProps>(({ success, theme }) => ({
|
||
...(success &&
|
||
{
|
||
// the overrides added when the new prop is used
|
||
}),
|
||
}));
|
||
```
|
||
|
||
#### CSS variables
|
||
|
||
{{"demo": "DynamicCSSVariables.js"}}
|
||
|
||
## 3. Global theme overrides
|
||
|
||
Material UI provides theme tools for managing style consistency between all components across your user interface.
|
||
Visit the [Component theming customization](/material-ui/customization/theme-components/) page for more details.
|
||
|
||
## 4. Global CSS override
|
||
|
||
To add global baseline styles for some of the HTML elements, use the `GlobalStyles` component.
|
||
Here is an example of how you can override styles for the `h1` elements:
|
||
|
||
{{"demo": "GlobalCssOverride.js", "iframe": true, "height": 100}}
|
||
|
||
The `styles` prop in the `GlobalStyles` component supports a callback in case you need to access the theme.
|
||
|
||
{{"demo": "GlobalCssOverrideTheme.js", "iframe": true, "height": 100}}
|
||
|
||
If you are already using the [CssBaseline](/material-ui/react-css-baseline/) component for setting baseline styles, you can also add these global styles as overrides for this component. Here is how you can achieve the same by using this approach.
|
||
|
||
{{"demo": "OverrideCssBaseline.js", "iframe": true, "height": 100}}
|
||
|
||
The `styleOverrides` key in the `MuiCssBaseline` component slot also supports callback from which you can access the theme. Here is how you can achieve the same by using this approach.
|
||
|
||
{{"demo": "OverrideCallbackCssBaseline.js", "iframe": true, "height": 100}}
|
||
|
||
:::success
|
||
It is a good practice to hoist the `<GlobalStyles />` to a static constant, to avoid rerendering. This will ensure that the `<style>` tag generated would not recalculate on each render.
|
||
:::
|
||
|
||
```diff
|
||
import * as React from 'react';
|
||
import GlobalStyles from '@mui/material/GlobalStyles';
|
||
|
||
+const inputGlobalStyles = <GlobalStyles styles={...} />;
|
||
|
||
function Input(props) {
|
||
return (
|
||
<React.Fragment>
|
||
- <GlobalStyles styles={...} />
|
||
+ {inputGlobalStyles}
|
||
<input {...props} />
|
||
</React.Fragment>
|
||
)
|
||
}
|
||
```
|