-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[docs] Revise "Component theming" and "How to customize" guides #31997
Changes from 12 commits
25b712c
100e7a3
974ea77
b5307a1
f29a278
5f2bb54
273cd2a
e3b4ce1
832c3ec
15e12f0
24b4bb2
c72125e
260faa1
9fd751e
6ffc1c3
b44e391
bda05ff
5c0bc5d
08070da
1429338
9cf2a44
af44cf2
36436d4
ef3c447
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -5,61 +5,59 @@ components: GlobalStyles | |||||
|
||||||
# How to customize | ||||||
|
||||||
<p class="description">You can easily customize the appearance of a MUI component.</p> | ||||||
<p class="description">Learn how to customize Material UI components by taking advantage of different strategies for specific use cases.</p> | ||||||
|
||||||
As components can be used in different contexts, there are several approaches to customizing them. Going from the narrowest use-case to the broadest, these are: | ||||||
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 style overrides](#2-reusable-style-overrides) | ||||||
1. [Dynamic variation](#3-dynamic-variation) | ||||||
1. [Global theme variation](#4-global-theme-variation) | ||||||
1. [Global CSS override](#5-global-css-override) | ||||||
|
||||||
## 1. One-off customization | ||||||
|
||||||
You might need to change the style of a component for a specific implementation, for which you have the following solutions available: | ||||||
To change the styles of _one single instance_ of a component, you can use one of the following options: | ||||||
|
||||||
### Use the `sx` prop | ||||||
### The `sx` prop | ||||||
|
||||||
The easiest way to add style overrides for a one-off situation is to use the [`sx` prop](/system/basics/#the-sx-prop) available on all MUI components. | ||||||
Here is an example: | ||||||
The [`sx` prop](/system/basics/#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"}} | ||||||
{{"demo": "SxProp.js" }} | ||||||
|
||||||
Next you'll see how you can use global class selectors for accessing slots inside the component. You'll also learn how to easily identify the classes which are available to you for each of the states and slots in the component. | ||||||
#### Overriding nested component styles | ||||||
|
||||||
### 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. | ||||||
|
||||||
You can use the browser dev tools to identify the slot for the component you want to override. It can save you a lot of time. | ||||||
The styles injected into the DOM by MUI rely on class names that [follow a simple pattern](/styles/advanced/#class-names): | ||||||
`[hash]-Mui[Component name]-[name of the slot]`. | ||||||
As an example, let's say you want to change the `Slider` component's thumb from a circle to a square. | ||||||
|
||||||
⚠️ These class names can't be used as CSS selectors because they are unstable, | ||||||
however, MUI applies global class names using a consistent convention: `Mui[Component name]-[name of the slot]`. | ||||||
First, use your browser's dev tools to identify the class for the component slot you want to override: | ||||||
|
||||||
Let's go back to the above demo. How can you override the slider's thumb? | ||||||
<img src="/static/images/customization/dev-tools.png" alt="dev-tools" width="796" style="margin-bottom: 16px;" /> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The change of docs/public/static/images/customization/dev-tools.png looks blurry on my screen. Am I the only one? I mean: a. https://mui.com/customization/how-to-customize/#overriding-nested-component-styles a. looks better on my end. I'm raising this because it's not the first time I see this problem. What do you think of limiting the resolution to x2, would it solve the problem? Otherwise, could we try a fixed integer increment? Currently, we are doing x3.28, maybe x3 or x4 would look crisp? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Huh... looks a bit blurry to me too, now that I'm looking at it again. But I did export at 2x (don't know where you got x3.28 from!). Though the blurriness could be because I increased the image size a bit. Let me see if I can tweak it properly. |
||||||
|
||||||
<img src="/static/images/customization/dev-tools.png" alt="dev-tools" width="406" /> | ||||||
Then, copy the target class of `MuiSlider-thumb`, place it inside the styles witihn the `sx` prop, and add your overrides. | ||||||
danilo-leal marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
In this example, the styles are applied with `.css-ae2u5c-MuiSlider-thumb` so the name of the component is `Slider` and the name of the slot is `thumb`. | ||||||
{{"demo": "DevTools.js"}} | ||||||
|
||||||
You now know that you need to target the `.MuiSlider-thumb` class name for overriding the look of the thumb: | ||||||
The styles injected into the DOM by Material UI rely on class names that all [follow a standard pattern](/styles/advanced/#class-names): | ||||||
`[hash]-Mui[Component name]-[name of the slot]`. | ||||||
|
||||||
{{"demo": "DevTools.js"}} | ||||||
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. | ||||||
|
||||||
> ⚠️ Note that these class names can't be used as CSS selectors because they are unstable. | ||||||
|
||||||
### Overriding styles with class names | ||||||
|
||||||
If you would like to override the styles of the components using classes, you can use the `className` prop available on each component. For overriding the styles of the different parts inside the component, you can use the global classes available for each slot, as described in the previous section. | ||||||
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](#overriding-nested-component-styles). | ||||||
|
||||||
You can find examples of this using different styles libraries in the [Styles library interoperability](/guides/interoperability/) guide. | ||||||
Visit the [Style library interoperability](/guides/interoperability/) guide to find examples of this approach using different styling libraries. | ||||||
|
||||||
### State classes | ||||||
|
||||||
The components special states, like _hover_, _focus_, _disabled_ and _selected_, are styled with a higher CSS specificity. | ||||||
[Specificity is a weight](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) that is applied to a given CSS declaration. | ||||||
States like _hover_, _focus_, _disabled_ and _selected_, are styled with a higher CSS specificity. To customize them, you'll need to **increase specificity**. | ||||||
|
||||||
In order to override the components' special states, **you need to increase specificity**. | ||||||
Here is an example with the _disable_ state and the Button component using a pseudo-class (`:disabled`): | ||||||
Here is an example with the _disable_ state and the `Button` component using a pseudo-class (`:disabled`): | ||||||
|
||||||
```css | ||||||
.Button { | ||||||
|
@@ -76,9 +74,9 @@ Here is an example with the _disable_ state and the Button component using a pse | |||||
<Button disabled className="Button"> | ||||||
``` | ||||||
|
||||||
Sometimes, you can't 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 such cases you can use a MUI equivalent of CSS pseudo-classes - **state classes**. | ||||||
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 | ||||||
|
@@ -96,15 +94,17 @@ Target the `.Mui-selected` global class name to customize the special state of t | |||||
<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/Specificity). | ||||||
|
||||||
#### Why do I need to increase specificity to override one component state? | ||||||
|
||||||
By design, the CSS specification makes the pseudo-classes increase the specificity. | ||||||
danilo-leal marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
For consistency with native elements, MUI increases the specificity of its custom state classes. | ||||||
This has one important advantage, it allows you to cherry-pick the state you want to customize. | ||||||
For consistency with native elements, Material UI increases the specificity of its custom state classes. | ||||||
This has one important advantage: it allows you to cherry-pick the state you want to customize. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think I fully understand the answer to this question. Here's what I gather:
Is that correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
danilo-leal marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
#### What custom state classes are available in MUI? | ||||||
#### What custom state classes are available in Material UI? | ||||||
|
||||||
You can rely on the following [global class names](/styles/advanced/#with-material-ui-core) generated by MUI: | ||||||
You can rely on the following [global class names](/styles/advanced/#with-material-ui-core) generated by Material UI: | ||||||
|
||||||
| State | Global class name | | ||||||
| :------------ | :------------------ | | ||||||
|
@@ -119,10 +119,10 @@ You can rely on the following [global class names](/styles/advanced/#with-materi | |||||
| required | `.Mui-required` | | ||||||
| selected | `.Mui-selected` | | ||||||
|
||||||
> ⚠️ Never style these state classes' names directly: | ||||||
> ⚠️ 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, impact all the components with unclear side-effects */ | ||||||
/* ❌ NOT OK */ | ||||||
.Mui-error { | ||||||
color: red; | ||||||
} | ||||||
|
@@ -133,28 +133,23 @@ You can rely on the following [global class names](/styles/advanced/#with-materi | |||||
} | ||||||
``` | ||||||
|
||||||
## 2. Reusable style overrides | ||||||
## 2. Reusable component | ||||||
|
||||||
If you find that you need the same overrides in multiple places across your application, you can use the [`styled()`](/system/styled/) utility to create a 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}} | ||||||
|
||||||
With it, you have access to all of a component's props to dynamically style the component. | ||||||
|
||||||
## 3. Dynamic variation | ||||||
### Dynamic overrides | ||||||
|
||||||
In the previous section, we learned how to override the style of a MUI component. | ||||||
Now, let's see how we can make these overrides dynamic. | ||||||
Here are four alternatives; each has its pros and cons. | ||||||
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 | ||||||
#### Dynamic CSS | ||||||
|
||||||
Using the `styled()` utility offers a simple way for adding dynamic styles based on props. | ||||||
> ⚠️ Note that if you are using TypeScript you will need to update the prop's types of the new component. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like we should move this back right before the demo showing how it should be altered in TypeScript. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before or after? Haven't altered its position, its in the same spot as in the current version. |
||||||
|
||||||
{{"demo": "DynamicCSS.js", "defaultCodeOpen": false}} | ||||||
|
||||||
> ⚠️ Note that if you are using TypeScript you will need to update the prop's types of the new component. | ||||||
|
||||||
```tsx | ||||||
import * as React from 'react'; | ||||||
import { styled } from '@mui/material/styles'; | ||||||
|
@@ -174,29 +169,19 @@ const StyledSlider = styled(Slider, { | |||||
})); | ||||||
``` | ||||||
|
||||||
### CSS variables | ||||||
#### CSS variables | ||||||
|
||||||
{{"demo": "DynamicCSSVariables.js"}} | ||||||
|
||||||
## 4. Global theme variation | ||||||
|
||||||
In order to promote consistency between components, and manage the user interface appearance as a whole, MUI provides a mechanism to apply global changes. | ||||||
|
||||||
Please take a look at the theme's [global overrides page](/customization/theme-components/) for more details. | ||||||
|
||||||
## 5. Global CSS override | ||||||
## 3. Global theme overrides | ||||||
|
||||||
Components expose [global class names](/styles/advanced/#with-material-ui-core) to enable customization with CSS. | ||||||
|
||||||
```css | ||||||
.MuiButton-root { | ||||||
font-size: 1rem; | ||||||
} | ||||||
``` | ||||||
Material UI provides theme tools for managing style consistency between all components across your user interface. | ||||||
Visit the [Component theming customization](/customization/theme-components/) page for more details. | ||||||
|
||||||
You can reference the [Styles library interoperability guide](/guides/interoperability/) to find examples of this using different styles libraries or plain CSS. | ||||||
## 4. Global CSS override | ||||||
|
||||||
If you just want to add some global baseline styles for some of the HTML elements, you can use the `GlobalStyles` component. Here is an example of how you can override styles for the `h1` elements. | ||||||
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}} | ||||||
|
||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that it was clearer before. We were explaining how to "identify the class" in logical order. How will people know that
MuiSlider-thumb
is the right selector when all they see is?We do no longer explain it in the flow, but at the bottom of the section. I think that it requires developers to do back and forth to understand the whole process, which is not ideal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. Revisited this one now, let me know your thoughts.