Material-UI (rebranded as MUI) recently released version 5, and there were significant changes to the syntax and systems used for styling components.
Material-UI v4 relied on JSS and the makeStyles
hook for component styling. MUI v5 has migrated to two options: styled
API or sx
API (<- definitely read this). The styled
API creates a new component that can easily be exported, and usage of the component is very clean with less inline prop code. The sx
prop is a superset of CSS that include built-in shorthands (i.e. mt={2} sets margin-top).
Both of the new APIs offer the following advantages over makeStyles
:
- One less import: the
@material-ui/core/styles
import is no longer needed - Less boiler-plate code: the makeStyles() and useStyles syntax are no longer needed and it results in several fewer lines of code written for each component
- Better abstraction:
sx
andstyled
both offer unique abstractions that simplify your code.sx
requires less code to do more styling, whilestyled
offers simplified reusability. I’ll explain this in-depth in the last section
Read my guide to the new styled()
API here.
makeStyles
is still supported, but it is deprecated. If you want to use it, it now requires the @mui/styles
import. Read my guide to makeStyles, useStyles, withStyles, and createStyles here.
A Code Sandbox link with full React code is in the Resources section.
Watch the YouTube version of this article or watch the embedded video below.
The Purpose of the SX Prop
Since MUI 5 created a new styling API, the primary questions to ask are “What is the sx prop and why should I use it?”. The docs explain it simply:
The `sx` prop is a shortcut for defining custom style that has access to the theme.
MUI sx prop docs
The sx prop simply requires very little code to accomplish lots of styling.
- Superset of CSS – sx can accept all CSS attributes (using JSS syntax) and it can accept all values from the “MUI System“. This is a vague name for their extensive list of rapid styling shortcuts.
- As mentioned above, it reduced the amount of code required for styling by getting rid of the makeStyles hook
- Theme aware – theme values can be accessed quickly.
sx={{ zIndex: 'modal' }}
is accessing theme.zIndex.modal. - Easy responsive styling – properties in sx can accept an object of with breakpoints as the key and CSS values as the values (an example is in the next section)
Example Code for the New MUI 5 SX Prop
I created the below TextField components only using styles passed to the sx
prop. The first is the ‘filled’ variant and the second is the ‘standard’ variant.

In each section below I’ll break down the different aspects of the styling code in the sx props of these TextFields.
import * as React from "react";
import TextField from "@mui/material/TextField";
import { SxProps } from "@mui/material/styles";
const style = {
mt: 2,
ml: 2,
width: { sm: 200, md: 300 },
backgroundColor: { xs: "secondary.light", sm: "#0000ff" },
boxShadow: 6
};
export default function CustomStyledTextField() {
return (
<>
<TextField
sx={{
...style,
mb: 2,
mr: 2,
border: "solid black 2px",
"& .MuiFilledInput-input": { color: "white" }
}}
id="standard-basic"
label="Filled"
variant="filled"
/>
<TextField
sx={{
...style,
"& .MuiOutlinedInput-root::before": {
content: `"$"`
},
}}
id="standard-basic"
label="standard"
variant="outlined"
/>
</>
);
}
(Here’s a guide to adding box shadow to MUI components)
An important syntax option available in es6 is object destructuring. It gives us a quick way to extract shared styles to a constant that can be reused.
const style = {//shared styling goes here}
sx={{
...style,
mb: 2,
mr: 2,
//etc
}}
Both of the TextFields have common styling. We certainly don’t want to copy/paste code, se we extract it. In the sx
prop after destructuring the style
const, simply include any additional styling specific to that TextField.
Superset and CSS Values in MUI SX
Below are some of the values in the ‘filled’ variant.
mb: 2, //System
mr: 2, //System
border: "solid black 2px" //CSS
mb
is margin-bottom and mr
is margin-right. These are shorthands available in the “MUI System”. Next is border
, which is standard CSS. These properties coexist and are equally viable in the sx
prop. This is why the prop is a ‘superset’ of CSS: all CSS values are valid, plus additional values from MUI’s styling system are valid.
Breakpoints in MUI SX
See 5 more examples of MUI sx breakpoints here.
Breakpoints in the sx prop are actually objects within a style value that map to theme breakpoints.
backgroundColor: { xs: "secondary.light", sm: "#0000ff" }
The xs
and sm
above have values of 0 and 600, respectively, in my code. These are the default values of the MUI theme object’s breakpoints. These can be customized.
Theme in MUI SX
In the breakpoints code above, notice the xs
value: "secondary.light"
. This is shorthand for theme.palette.secondary.light
.
Even the way I accessed the breakpoints is a shorthand for accessing theme.breakpoints.values.xs
(or .sm).
This screenshot from the MUI v5 theme object docs shows all the different theme values that can be quickly accessed using the sx
prop.

Styling Nested Components with SX
One of my favorite aspects of the sx
component is that it has the capability to use complex CSS selectors.
"& .MuiFilledInput-input": { color: "white" }
This selects children elements with class .MuiFilledInput-input
.
The TextField is composed of several components, which means in the DOM it is composed of several elements. It’s important to know that sx
styles are applied to the topmost element possible in the DOM.

The screenshot couldn’t quite capture all the styling, but further down in the list of stylings we would see the styles we gave to the sx
prop. They are all applied to the root div of the TextField. A child element further down in the DOM has class .MuiFilledInput-input.
MUI SX Pseudo Selectors (‘before’ and ‘hover’)
See 4 examples of hover in MUI sx here.
I created a complex selector that applies a special character to the ::before
pseudo-element of the Input element of outlined
variant TextFields.
sx={{
..styles,
"& .MuiOutlinedInput-root::before": {
content: `"$"`
}
}}
Notice the double colon. This is new in CSS3 to distinguish between pseudo-elements and pseudo-classes. If I was adding hover, it would have only a single colon like "& .MuiOutlinedInput-root:hover"
. I would also target the fieldset element, and you can see exactly how I add hover to the TextField with MUI sx here.
Read about changing MUI TextField border color on focus, disabled, and more here.
SxProps: TypeScript Typing for the MUI `sx` Prop
Special thanks to reader “AC” who reminded me to include TypeScript typing in this post. If you are using TypeScript, you need typing for your sx
prop values if you abstract them to a constant. Here’s an example:
import { SxProps } from "@mui/system";
const style: SxProps = {
mt: 2,
ml: 2,
width: { sm: 200, md: 300 },
backgroundColor: { xs: "secondary.light", sm: "#0000ff" },
boxShadow: 6
};
The style const would be passed to the sx
prop in the JSX.
Interestingly, the docs recommend (or used to recommend) a different import:
import { SxProps } from '@mui/material/styles';
I got an error that this was an invalid import when I tried it in CodeSandbox. Others have gotten this error as well.
At the time of writing this post, I recommend importing from "@mui/system"
.
MUI SX API vs MUI Styled() API
If you’ve upgraded to MUI 5 and are wondering which of the two styling options are better, review this rundown of relative strengths (here’s a full article on MUI sx vs styled vs theme overrides):
styled API:
- With
styled
, You get to write CSS….using CSS syntax.sx
still uses JSS because it lives in JSX world. styled
is a simpler abstraction. In this example, all the Root component code is pulled out of the JSX. In practice, it should be in its own file and the Root component would simply be imported where needed. Similar abstraction can be accomplished withsx
but it’s not the purpose of thesx
API.- The styled library is a popular library with about 3 million weekly downloads (Sept 2021). Many devs will be familiar with it.
sx API:
- It can be passed typical CSS attributes as well as all in-house MUI spacing shorthands (see the list here)
- It simplifies access to the theme, i.e.
'primary.main'
instead oftheme.palette.primary.main
. - Responsive styling is incredibly easy and requires very little code
FAQs
The Material-UI sx prop can use conditionals in two ways. First, it can use conditionals to set the attribute value. Here is example code:<TextField sx={{ color: isPrimary ? 'primary.main' : 'secondary.main'}}/>
Second, sx can use conditionals to set styling objects. Here is example code:<TextField sx={ isPrimary ? primaryStyles : secondaryStyles}/>
The Material-UI sx prop is “theme aware”. This means that all the values of the default theme object can be accessed in the sx prop. Here is example code:sx={{ zIndex: 'modal' }}
. This is accessing the theme.zIndex.modal
value.
Resources
This MUI v5 tutorial shows an app created with both styling APIs.
Excellent, I was looking for updated information since I was using makestyles with mui 5 and it was not working for me, I see why, thank you very much.
I am glad this information helped!
Thanks, This is what I was looking for
if you are on tsx (typescript) files, ensure you do it as
import { SxProps } from ‘@mui/material’
..
const style = {
mt: 2,
ml: 2,
width: { sm: 200, md: 300 },
backgroundColor: { xs: “secondary.light”, sm: “#0000ff” },
boxShadow: 6
} as SxProps;
Hey AC, thanks for sharing!
styled isn’t *really* supported – React 18 breaks LOTS of things and they will NOT fix them. So if you want React 18 goodness, then you have to migrate or use something like tss-react (even there there is lots that isn’t implemented, so still lots of work to do…)
Hi Anton, tss-react is a good hook alternative to the styled API, thanks for mentioning it. Here’s the documentation for anyone interested in learning more.
This looked like a very helpful website, but I couldn’t focus on the content because the ads kept moving. I understand and do not object to ads to support helpful websites, but the moving ads seriously detract from your message. In the future I will skip this URL.
Hi Michael, apologies for the bad experience. I believe the “moving ad” was actually a video version of this post that I embedded (it plays an ad before the video starts). It does jump down to the bottom corner. I’ve found some people have different learning styles and appreciate the videos, but I understand your concerns. Thanks for sharing.