Material UI v5 recently released their new design system the Sx prop. The property includes style properties from CSS and @mui/system. Taking the MUI styling system to the next level. Personally I loved the new style engine from Material UI v5, enabling me to build Web Apps totally using the Material UI's ecosystem. Being used to the clean method of composing CSS classes using classnames package, I found composing and conditionally chaing the sx
props a bit unclean.
The Feature
If you're totally new to mui v5, Let's first look at what exactly is sx props. sx
prop is prop used in MuiV5 design system, that leverages mui shorthands and native css properties to provide a good styling experience. Below is a basic example of its usage.
import { Box } from "@mui/material";
export default function App() {
return (
<Box className="App">
<h1>mui-sx demo</h1>
<Box
// Passing Sx Prop Here
sx={{
mt: 2,
width: 500,
height: 500,
background: "yellow",
border: 1
}}
/>
</Box>
);
}
As seen, sx prop is a JS object comprising of sx properties i.e mui short hands and native css props.
The Problem
Being a JS object, using the sx prop across the markdown might look unclean. There might be usecases where you'd want to reuse some styling or apply conditionally styling.
Lets look at another example where in you need to conditionally color an element based on React state, also enforce modular styling pattern to ensure better reusability.
import { Button } from "@mui/material";
import React from "react";
import { Box, Stack } from "@mui/material";
const sxBox = {
width: "100%",
height: 500
};
const sxBordered = {
border: 1
};
const sxNight = {
backgroundColor: "#000"
};
const sxDay = {
backgroundColor: "yellow"
};
export default function App() {
const [isDay, setDay] = React.useState(true);
return (
<>
<Stack className="App" spacing={2}>
<h1>mui-sx demo</h1>
<div>Click toggle button below</div>
<Box
sx={
// Follow are applied unconditionally
{
...sxBox,
...sxBordered,
...(isDay && sxNight),
...(!isDay && sxDay)
}
// Follow sx applied when isDay === false
}
/>
<Button variant="contained" onClick={() => setDay(!isDay)}>
Toggle
</Button>
</Stack>
</>
);
}
As seen in the sandbox, one might need lots of spread operators (...)
and ternary conditions to implement composition of the sx prop. If you have worked on huge projects with modular css patterns, scaling above might get ugly.
The Solution
This is where mui-sx comes to rescue. Its a tiny JS library based off classnames, that helps elegantly compse the sx prop. Let's look at the above example written using mui-sx
.
import sx from "mui-sx";
import { Button } from "@mui/material";
import React from "react";
import { Box, Stack } from "@mui/material";
const sxBox = {
width: "100%",
height: 500
};
const sxBordered = {
border: 1
};
const sxNight = {
backgroundColor: "#000"
};
const sxDay = {
backgroundColor: "yellow"
};
export default function App() {
const [isDay, setDay] = React.useState(true);
return (
<>
<Stack className="App" spacing={2}>
<h1>mui-sx demo</h1>
<div>Click to toggle color</div>
<Box
sx={sx(
// Follow are applied unconditionally
sxBox,
sxBordered,
// Follow sx applied when isDay === true
{
condition: isDay,
sx: sxDay
},
// Follow sx applied when isDay === false
{
condition: !isDay,
sx: sxNight
}
)}
/>
<Button variant="contained" onClick={() => setDay(!isDay)}>
Toggle
</Button>
</Stack>
</>
);
}
Much Cleaner! The syntax is very close to classnames and if you are someone that has been using classnames for a while then you might enjoy using mui-sx.
Link to the NPM Package: mui-sx
Hope that was helpful š
If you have any questions/confusions/suggestions/corrections, Please do post down in the comments section below.
Rohan Salunke (https://okrohan.bio.link/)
Top comments (4)
This article was quite informative.
However, IMHO, it's probably better NOT to use
sx
when styling a component conditionally (even if "mui-sx" allows you to do so smoothly).According to MUI's documentation...
If a component's style needs to change conditionally, I'd opt for the styled-components API
You can already pass arrays to the sx prop -- what does this add?
My preference for reuse styling is themeing. sx props for one call thing, when theming not possible.
Yep! That's the way to go with mui.