The Ultimate Guide to the Material-UI Theme Object: Breakpoints, Overrides, Shadows, Typography, and More

***UPDATED to include MUI v5 Global Style Overrides code**

Many developers experienced with Material-UI have used the theme object to customize the color palette for their apps.

However, palette is one of many configurable objects within the theme object. There are 12 top-level fields within the Theme object that can be customized to give your app the exact look-and-feel that you desire (see the entire default theme object here).

In this guide, I will demo commonly configured fields: breakpoints, overrides, shadows, and typography. I have an in-depth guide for creating a unique theme palette in a separate article.

I will also briefly explain transitions and zIndex.

The Code Sandbox with full React code is in the Resources section. A YouTube version of this article is also in the Resources section. The snippet of code below the Table of Contents is the custom theme created with createMuiTheme and is discussed throughout this article.

const customTheme = createMuiTheme({
  breakpoints: {
    values: {
      xs: 0,
      sm: 300,
      md: 960,
      lg: 1280,
      xl: 1920
    }
  },
  typography: {
    paper: {},
    div: {
      fontStyle: "italic"
    }
  },
  //Material-UI v4 method
  overrides: {
    MuiContainer: {
      root: {
        backgroundColor: "grey"
      },
      maxWidthSm: { 
        fontSize: 20
      }
    }
  }
  //MUI v5 method
  components: {
    MuiContainer: {
      styleOverrides: {
        root: {
          backgroundColor: "grey"
        },
        maxWidthSm: {
          fontSize: 20
        }
      }
    }
  }
});

customTheme.shadows.push(
  "0px 13px 17px -9px rgba(0,0,0,0.4),0px 26px 40px 4px rgba(0,0,0,0.2),0px 10px 48px 9px rgba(0,0,0,0.13)"
);

Theme Breakpoints

The breakpoints object is composed of three sections:

  • keys – the labels used as props to designate a certain screensize at which to break. Keys are used because they are memorable, i.e. ‘md’ is easier to remember than 960.
  • values – the screen pixel width at which to change behavior. Often these are used to change layout or styling based on screen size.
  • direction functions – these provide control of behavior at breakpoints. Using the defaults below, theme.breakpoints.down("sm") takes effect only when screen size is below 960px and theme.breakpoints.up("sm") takes effect only when screen size is above 600px. Notice how these use the minimum and maximum of the range differently.

Typically you don’t want to change anything except the values object. The keys are an industry standard and other devs would be surprised if the direction functions behaved differently than expected.

One important thing to notice is that when I changed the values object, I couldn’t simply change one value. I had to pass a value for every key. In other words, even though I only cared about setting a custom “sm” value, I had to set a value for all breakpoints or else they didn’t work.

breakpoints: {
  values: {
    xs: 0,
    sm: 300,
    md: 960,
    lg: 1280,
    xl: 1920
  }
}

Using the new breakpoint value is exactly the same as using the default “sm” breakpoint. Here I used it to set a max width of 300px on my container.

<Container maxWidth="sm">Custom Container Text</Container>

I also used the custom breakpoint values in the paper class to set padding based on screen size. Open up the Code Sandbox and adjust the viewport to see the effect. The padding on the Paper component should grow and shrink.

 paper: {
  ...theme.typography.paper,
  padding: 8,
  [theme.breakpoints.down("sm")]: {
    padding: 6
  },
  [theme.breakpoints.down("xs")]: {
    padding: 4
  }
}

Theme Overrides

The overrides object is fascinating: it is composed of objects that hook into the Material-UI global styling API.

In my code, I overrode the MuiContainer object’s root and maxWidthSm objects. These correspond to the .MuiContainer-root and .MuiContainer-maxWidthSm classes applied to DOM elements when Material-UI renders a Container with the maxWidth prop set to “sm”.

//Theme.jsx
//Material-UI v4 method
overrides: {
  MuiContainer: {
    root: {
      backgroundColor: "grey"
    },
    maxWidthSm: { fontSize: 20 }
  }
}

//MUI V5 method
components: {
  MuiContainer: {
    styleOverrides: {
      root: {
        backgroundColor: "grey"
      },
      maxWidthSm: {
        fontSize: 20
      }
    }
  }
}

//ThemeExtended.jsx return function
<Container maxWidth="sm">Custom Container Text</Container>

Anything listed in the CSS section of a component’s API can be overridden. Here’s a few examples:

overrides: {
  MuiCardHeader: {
    action: {}
  },

  MuiButton: {
    outlinedPrimary: {}
  },

  MuiGrid: {
    zeroMinWidth: {},
    directionXsColumn: {}
  }
}

In this example of extending the Typography object, I overrode the .MuiTypography-root class.

Here’s an example of overriding Button styling in MUI v5.

Theme Shadow

The Material-UI shadows system is a simple approach for applying shadow to components.

By default, the possible shadow values are stored in an array containing 25 values (0 thru 24, of course)

A screenshot of some of the default shadow values

These shadow stylings can quickly be applied to components either via the elevation or boxShadow props. Which prop simply depends on the component. For example, the Box component uses boxShadow while the Paper component uses elevation.

I added an additional extra dark shadow to the theme I created. My theme now has 26 values (0 thru 25) that can be accessed. I simply pushed the additional value to the customTheme.shadows array.

customTheme.shadows.push(
  "0px 13px 17px -9px rgba(0,0,0,0.4),0px 26px 40px 4px rgba(0,0,0,0.2),0px 10px 48px 9px rgba(0,0,0,0.13)"
);

Now to use my new shadow style, I simply pass it to the elevation prop:

<Paper elevation={25} className={classes.paper}>

Theme Typography

The typography system in Material-UI is a customizable and extendable object. It can be automatically applied via a custom theme and also individually accessed in components’ JSS classes. I will show code examples of both.

Part of the theme.typography object

The typography object is composed of default typography values and also objects representative of default values for different elements. Both can be modified or accessed.

In my custom theme I created a div and paper typography and set the div typography to fontStyle: "italic".

typography: {
  paper: {},
  div: {
    fontStyle: "italic"
  }
}

I still have to access the div value in classes I create.

Here the theme is selectively applied in the ThemeExtended component’s JSS classes. I can access default values such as theme.typography.button.lineHeight and theme.typography.overline.textTransform.

Notice also that I access the theme.typography.div object I created and quickly apply it using the spread operator.

const useStyles = makeStyles((theme) => ({
  paper: {
    ...theme.typography.paper,
    padding: 8,
    [theme.breakpoints.down("sm")]: {
      padding: 6
    },
    [theme.breakpoints.down("xs")]: {
      padding: 4
    }
  },
  div: {
    ...theme.typography.div,
    lineHeight: theme.typography.button.lineHeight,
    textTransform: theme.typography.overline.textTransform,
    marginBottom: 16
  }
}));

Theme Transitions and ZIndex

Default theme transitions and zIndex are used by quite a few components in Material-UI. For example, a div can be wrapped in <Fade /> or <Collapse /> to quickly apply animation. Other components naturally have a z-axis aspect, and there needs to be a hierarchy when these components are used together.

Below we see some of the defaults in the Material-UI theme object. Any of these can be modified. For example, set theme.zIndex.drawer = 9999 to make the Drawer the “highest” component in your custom theme.

Once again, simply create a custom theme, update the zIndex or transitions values accordingly, and make sure to pass your theme to components via a <ThemeProvider />.

Framer Motion is another library that offers very robust transitions.

Resources

Are you looking for training in Material-UI? Check out my review of the best Material-UI course in Udemy, which has 40+ hours of content and a 30-day money back guarantee

Do you want to expand your JavaScript knowledge? Try these 50 challenging questions.

Code Sandbox link.

YouTube version of this article.

Here’s how to update the theme shapes.borderRadius value.

Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.