Skip to content
+

Usage

Learn the basics of working with MUI System and its utilities.

Why use MUI System?

MUI System's sx prop lets you avoid writing unnecessary styled-component code, and instead define styles directly within the component itself. This is especially useful for one-off components with custom designs.

The following code samples illustrate the difference between styled-components and sx:

Sessions
98.3 K
18.7%
vs. last week
  1. Using the styled-components API:
const StatWrapper = styled('div')(
  ({ theme }) => `
  background-color: ${theme.palette.background.paper};
  box-shadow: ${theme.shadows[1]};
  border-radius: ${theme.shape.borderRadius}px;
  padding: ${theme.spacing(2)};
  min-width: 300px;
`,
);

const StatHeader = styled('div')(
  ({ theme }) => `
  color: ${theme.palette.text.secondary};
`,
);

const StyledTrend = styled(TrendingUpIcon)(
  ({ theme }) => `
  color: ${theme.palette.success.dark};
  font-size: 16px;
  vertical-alignment: sub;
`,
);

const StatValue = styled('div')(
  ({ theme }) => `
  color: ${theme.palette.text.primary};
  font-size: 34px;
  font-weight: ${theme.typography.fontWeightMedium};
`,
);

const StatDiff = styled('div')(
  ({ theme }) => `
  color: ${theme.palette.success.dark};
  display: inline;
  font-weight: ${theme.typography.fontWeightMedium};
  margin-left: ${theme.spacing(0.5)};
  margin-right: ${theme.spacing(0.5)};
`,
);

const StatPrevious = styled('div')(
  ({ theme }) => `
  color: ${theme.palette.text.secondary};
  display: inline;
  font-size: 12px;
`,
);

return (
  <StatWrapper>
    <StatHeader>Sessions</StatHeader>
    <StatValue>98.3 K</StatValue>
    <StyledTrend />
    <StatDiff>18.77%</StatDiff>
    <StatPrevious>vs last week</StatPrevious>
  </StatWrapper>
);
  1. Using MUI System:
<Box
  sx={{
    bgcolor: 'background.paper',
    boxShadow: 1,
    borderRadius: 1,
    p: 2,
    minWidth: 300,
  }}
>
  <Box sx={{ color: 'text.secondary' }}>Sessions</Box>
  <Box sx={{ color: 'text.primary', fontSize: 34, fontWeight: 'medium' }}>
    98.3 K
  </Box>
  <Box
    component={TrendingUpIcon}
    sx={{ color: 'success.dark', fontSize: 16, verticalAlign: 'sub' }}
  />
  <Box
    sx={{
      color: 'success.dark',
      display: 'inline',
      fontWeight: 'medium',
      mx: 0.5,
    }}
  >
    18.77%
  </Box>
  <Box sx={{ color: 'text.secondary', display: 'inline', fontSize: 12 }}>
    vs. last week
  </Box>
</Box>

The sx prop

MUI System's core utility is the sx prop, which gives you a quick and efficient way to apply the correct design tokens directly to a React element.

This prop provides a superset of CSS (that is it contains all CSS properties and selectors in addition to custom ones) that maps values directly from the theme, depending on the CSS property used. It also simplifies the process of defining responsive values by referring to the breakpoints defined in the theme.

Visit the sx prop page for complete details.

Responsive demo

The following demo shows how to use the sx prop to apply custom styles and create a complex UI component using the Box wrapper alone. Resize the window to see the responsive breakpoints:

The house from the offer.
123 Main St, Phoenix AZ$280,000 — $310,000
Confidence score: 85%
Press Enter to start editing

When to use MUI System

The sx prop is best suited for applying one-off styles to custom components.

This is in contrast to the styled-components API, which is ideal for building components that need to support a wide variety of contexts. These components are used in many different parts of the application and support different combinations of props.

Performance tradeoffs

MUI System relies on CSS-in-JS. It works with both Emotion and styled-components.

Pros

  • 📚 The sx prop uses a superset of CSS, so the syntax will be immediately familiar to you if you know CSS already. It also offers (optional) shorthand definitions that can save you time if you put in a little work to learn them upfront. These are documented in the Style utilities section of the primary navigation to the left.
  • 📦 The System auto-purges, so that only the CSS that's used on the page is sent to the client. The initial bundle size cost is fixed—it doesn't get any larger as you add more CSS properties. You pay the cost of @emotion/react and @mui/system. The total size is ~15 kB gzipped. But if you are already using an MUI Core component library like Material UI, then it comes with no extra overhead.

Cons

Runtime performance takes a hit.

Benchmark case Code snippet Time normalized
a. Render 1,000 primitives <div className="…"> 100ms
b. Render 1,000 components <Div> 112ms
c. Render 1,000 styled components <StyledDiv> 181ms
d. Render 1,000 Box <Box sx={…}> 296ms

Visit the benchmark folder for a reproduction of the metrics above.

We believe that for most use cases it's fast enough, but there are simple workarounds when performance becomes critical. For instance, when rendering a list with many items, you can use a CSS child selector to have a single "style injection" point (using d. for the wrapper and a. for each item).

API tradeoff

MUI System's unifying sx prop helps to maintain the separation of concerns between CSS utilities and component business logic.

For instance, a color prop on a button impacts multiple states (hover, focus, etc.), and is distinct from the CSS color property.

Only the Box, Stack, Typography, and Grid components accept MUI System properties as props for this reason. These components are designed to solve CSS problems—they are CSS component utilities.

Where to use MUI System

The sx prop can be used in four different locations:

Core components

All Material UI and Joy UI components support the sx prop.

Box

Box is a lightweight component that gives access to the sx prop, and can be used as a utility component, and as a wrapper for other components. It renders a <div> element by default.

Custom components

In addition to MUI System components, you can add the sx prop to your custom components too, by using the styled utility from @mui/material/styles.

import { styled } from '@mui/material/styles';

const Div = styled('div')``;

Any element with the babel plugin

Visit the open GitHub issue regarding this topic to learn more.

How to use MUI System

Design tokens in the theme

Visit the System properties page to learn how the different CSS (and custom) properties are mapped to the theme keys.

Shorthands

There are many shorthands available for various CSS properties. These are documented on their respective Style utilities pages. Here is an example of a few:

<Box
  sx={{
    boxShadow: 1, // theme.shadows[1]
    color: 'primary.main', // theme.palette.primary.main
    m: 1, // margin: theme.spacing(1)
    p: {
      xs: 1, // [theme.breakpoints.up('xs')]: { padding: theme.spacing(1) }
    },
    zIndex: 'tooltip', // theme.zIndex.tooltip
  }}
>

These shorthands are optional—they're great for saving time, but not necessary to use

Superset of CSS

The sx prop supports CSS syntax including child and pseudo-selectors, media queries, raw CSS values, and more. Here are a few examples of how you can implement these CSS features:

  • Using pseudo-selectors:

    <Box
      sx={{
        // some styles
        ":hover": {
          boxShadow: 6,
        },
      }}
    >
    
  • Using media queries:

    <Box
      sx={{
        // some styles
        '@media print': {
          width: 300,
        },
      }}
    >
    
  • Using nested selector:

    <Box
      sx={{
        // some styles
        '& .ChildSelector': {
          bgcolor: 'primary.main',
        },
      }}
    >
    

Responsive values

The sx prop simplifies the process of defining and implementing responsive breakpoints. You can define a set of breakpoints in two different ways: as an object, or as an array.

Breakpoints as an object

The first option for breakpoints is to define them as an object, using the breakpoint values as keys. Note that each property for a given breakpoint also applies to all larger breakpoints in the set. For example, width: { lg: 100 } is equivalent to theme.breakpoints.up('lg').

The following demo shows how to define a set of breakpoints using the object syntax:

This box has a responsive width.
Press Enter to start editing

Breakpoints as an array

The second option is to define your breakpoints as an array, from smallest to largest. Here's what that looks like:

This box has a responsive width.
Press Enter to start editing

You can skip breakpoints with the null value:

<Box sx={{ width: [null, null, 300] }}>This box has a responsive width.</Box>

Custom breakpoints

You can also specify your own custom breakpoints, and use them as keys when defining the breakpoints object. Here is an example of how to do that:

import * as React from 'react';
import Box from '@mui/material/Box';
import { createTheme, ThemeProvider } from '@mui/material/styles';

const theme = createTheme({
  breakpoints: {
    values: {
      mobile: 0,
      tablet: 640,
      laptop: 1024,
      desktop: 1280,
    },
  },
});

export default function CustomBreakpoints() {
  return (
    <ThemeProvider theme={theme}>
      <Box
        sx={{
          width: {
            mobile: 100,
            laptop: 300,
          },
        }}
      >
        This box has a responsive width
      </Box>
    </ThemeProvider>
  );
}

If you are using TypeScript, you will also need to use module augmentation for the theme to accept the above values.

declare module '@mui/material/styles' {
  interface BreakpointOverrides {
    xs: false; // removes the `xs` breakpoint
    sm: false;
    md: false;
    lg: false;
    xl: false;
    tablet: true; // adds the `tablet` breakpoint
    laptop: true;
    desktop: true;
  }
}

Theme getter

If you wish to use the theme for a CSS property that is not supported natively by MUI System, then you can use a function as the value, in which you can access the theme object. The following demo shows how this works:

Border color with theme value.
Press Enter to start editing