Search code examples
cssreactjsmaterial-uiemotion

How to override default styles in Material UI v5 compared to v4?


In Material UI v4, I used makeStyles and withStyles from @mui/styles to override the default styles for components, which was a straightforward approach to customize the look and feel of my application. However, after upgrading to Material UI v5, makeStyles has been deprecated and the styling system seems to have changed significantly with the introduction of the sx prop and the styled API.

How can I override default component styles (like changing the MuiButton padding or color) in Material UI v5? What are the best practices now for overriding default styles globally or locally in MUI v5, and how does it differ from v4?

Would also appreciate examples for both global overrides (like theming) and specific overrides (like using the sx prop or styled API).

Additional query:

If I need to change the style of a component depends on where it is used or say if I am creating a custom component using any of the mui component. Like in this example:

import { Box } from "@mui/material";

function App() {
  return (
    <Box sx={{ bgcolor: (theme) => theme.palette.grey[100], p: 4 }}>
      <span>Hello world</span>
    </Box>
  );
}

export default App;

I am able to use sx prop to update the style for the mui component but for the span inside I cannot use sx prop but still I need to add a color from the theme.


Solution

  • I hope it helps.

    Here is the basic idea

    • There are few palettes

    • like primary, secondary etc

    • To customize the color

      • Use the palette property to modify
        • In the example, I just updated the primary
        • You can do it for secondary, success, error, info, warning
        • You can also add more properties but requires typescript fix, globally
    • To customize the components globally use components property

      • MuiButton
        • Provided an example for this
      • MuiTable
      • MuiInput etc...
        • Now think about default colors and design
        • Also care about their variants
    import { createTheme, ThemeOptions, Theme } from '@mui/material/styles'
    
    const primary = {
      main: '#7A5AF8',
      light: '#F4F3FF',
      dark: '#3E1C96',
      contrastText: '#FFFFFF',
      50: '#F4F3FF',
      100: '#EBE9FE',
      200: '#D9D6FE',
      300: '#BDB4FE',
      400: '#9B8AFB',
      500: '#7A5AF8',
      600: '#6938EF',
      700: '#5925DC',
      800: '#4A1FB8',
      900: '#3E1C96'
    }
    
    export const lightTheme: ThemeOptions = createTheme({
      palette: {
        primary,
      },
      components: {
        MuiButton: {
          defaultProps: {
            disableRipple: true,
            variant: 'contained'
          },
          styleOverrides: {
            root: {
              textTransform: 'none',
              borderRadius: '6px',
              padding: '10px 16px',
              fontWeight: 500
            }
          },
          variants: [
            {
              props: {
                variant: 'contained'
              },
              style: ({ theme }: { theme: Theme }) => ({
                paddingTop: theme.spacing(0.75),
                paddingBottom: theme.spacing(0.75),
              })
            }
          ]
        }
      }
    })
    
    
    • Make a seperate component to provide the theme
    import CssBaseline from '@mui/material/CssBaseline'
    import { ThemeProvider as MuiThemeProvider } from '@mui/material/styles'
    import { lightTheme } from 'your-constant-location'
    
    
    const ThemeProvider = ({ children }) => {
       return (
         <MuiThemeProvider theme={lightTheme}>
           <CssBaseline />
           <>{children}</>
         </MuiThemeProvider>
       )
    }
     
    

    Use this provider in your root app

    const App = () => {
      return (
        <ThemeProvider>
           ...your app
        </ThemeProvider>
    
      )
    }
    

    Customize Locally

    <Box
      sx={{
        bgcolor: (theme) => theme.palette.grey[100],
        p: 4,
        '& span': {
          color: 'blue',
          fontWeight: 'bold',
          fontSize: '20px',
        },
      }}
    >
      <span>Hello world</span>
    </Box>