Skip to content

Customizing components

You can easily customize the appearance of a Material-UI component.

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:

  1. One-off customization
  2. Reusable style overrides
  3. Dynamic variation
  4. Global theme variation
  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:

Use the sx prop

The easiest way to add style overrides for a one-off situation is to use the sx prop available on all Material-UI components. Here is an example:

<Slider
  defaultValue={30}
  sx={{
    width: 300,
    color: 'success.main',
  }}
/>

Next you'll see how you can 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

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 Material-UI rely on class names that follow a simple pattern: [hash]-Mui[Component name]-[name of the slot].

⚠️ These class names can't be used as CSS selectors because they are unstable, however, Material-UI applies global class names using a consistent convention: Mui[Component name]-[name of the slot].

Let's go back to the above demo. How can you override the slider's thumb?

dev-tools

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.

You now know that you need to target the .MuiSlider-thumb class name for overriding the look of the thumb:

<Slider
  defaultValue={30}
  sx={{
    width: 300,
    color: 'success.main',
    '& .MuiSlider-thumb': {
      borderRadius: '1px',
    },
  }}
/>

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.

You can find examples of this using different styles libraries in the Styles library interoperability guide.

Pseudo-classes

The components special states, like hover, focus, disabled and selected, are styled with a higher CSS specificity. Specificity is a weight that is applied to a given CSS declaration.

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):

.Button {
  color: black;
}

/* Increase the specificity */
.Button:disabled {
  color: white;
}
<Button disabled className="Button">

Sometimes, you can't use a pseudo-class, as the state doesn't exist in the web specification. Let's take the menu item component and the selected state as an example. You can use the .Mui-selected global class name to customize the special state of the MenuItem component:

.MenuItem {
  color: black;
}

/* Increase the specificity */
.MenuItem.Mui-selected {
  color: blue;
}
<MenuItem selected className="MenuItem">

Why do I need to increase specificity to override one component state?

By design, the CSS specification makes the pseudo-classes increase the specificity. For consistency with native elements, Material-UI increases the specificity of its custom pseudo-classes. This has one important advantage, it allows you to cherry-pick the state you want to customize.

What custom pseudo-classes are available in Material-UI?

You can rely on the following global class names generated by Material-UI:

State Global class name
active .Mui-active
checked .Mui-checked
disabled .Mui-disabled
error .Mui-error
focused .Mui-focused
focus visible .Mui-focusVisible
required .Mui-required
expanded .Mui-expanded
selected .Mui-selected

⚠️ Never style these pseudo-class class names directly:

/* ❌ NOT OK, impact all the components with unclear side-effects */
.Mui-error {
  color: red;
}

/* ✅ OK */
.MuiOutinedInput-root.Mui-error {
  color: red;
}

2. Reusable style overrides

If you find that you need the same overrides in multiple places across your application, you can use the experimentalStyled() utility for creating a reusable component:

import * as React from 'react';
import Slider from '@material-ui/core/Slider';
import { alpha, experimentalStyled } from '@material-ui/core/styles';

const SuccessSlider = experimentalStyled(Slider)(({ theme }) => ({
  width: 300,
  color: theme.palette.success.main,
  '& .MuiSlider-thumb': {
    '&:hover, &.Mui-focusVisible': {
      boxShadow: `0px 0px 0px 8px ${alpha(theme.palette.success.main, 0.16)}`,
    },
    '&.Mui-active': {
      boxShadow: `0px 0px 0px 14px ${alpha(theme.palette.success.main, 0.16)}`,
    },
  },
}));

export default function StyledCustomization() {
  return <SuccessSlider defaultValue={30} />;
}

With it, you have access to all of a component's props to dynamically style the component.

3. Dynamic variation

In the previous section, we learned how to override the style of a Material-UI component. Now, let's see how we can make these overrides dynamic. Here are four alternatives; each has its pros and cons.

Dynamic CSS

Class name branch

CSS variables

<React.Fragment>
  <FormControlLabel
    control={
      <Switch
        checked={vars === successVars}
        onChange={handleChange}
        color="primary"
        value="dynamic-class-name"
      />
    }
    label="Success"
  />
  <CustomSlider style={vars} defaultValue={30} sx={{ mt: 1 }} />
</React.Fragment>

Theme nesting

<React.Fragment>
  <FormControlLabel
    control={
      <Switch
        checked={success}
        onChange={handleChange}
        color="primary"
        value="dynamic-class-name"
      />
    }
    label="Success"
  />
  <ThemeProvider theme={theme}>
    <Slider defaultValue={30} sx={{ width: 300, mt: 1 }} />
  </ThemeProvider>
</React.Fragment>

4. Global theme variation

In order to promote consistency between components, and manage the user interface appearance as a whole, Material-UI provides a mechanism to apply global changes.

Please take a look at the theme's global overrides page for more details.

5. Global CSS override

Components expose global class names to enable customization with CSS.

const GlobalCss = withStyles({
  // @global is handled by jss-plugin-global.
  '@global': {
    '.MuiButton-root': {
      fontSize: '1rem',
    },
  },
})(() => null);

// …

<GlobalCss />;

If you are using the CssBaseline component to apply global resets, it can also be used to apply global styles. For instance:

const theme = createMuiTheme({
  components: {
    MuiCssBaseline: {
      styleOverrides: {
        '@global': {
          html: {
            WebkitFontSmoothing: 'auto',
          },
        },
      },
    },
  },
});

// ...
return (
  <ThemeProvider theme={theme}>
    <CssBaseline />
    {children}
  </ThemeProvider>
);
<React.Fragment>
  <GlobalCss />
  <Button>font-size: 1rem</Button>
</React.Fragment>