NEHNO


BlogTechAbout

MUI 5 - Styled / SX

Andrew Lai
Andrew Lai
June 3rd, 2022
Cover Image for MUI 5 - Styled / SX

⁠MUI 5 is a bit different from V4. One thing that many will need to get used to is the styling switch from JSS to @emotion.⁠ MUI now has the styled utility or the sx prop. You can read more about the differences here but the gist of it is that sx is more for one offs and responsive values while styled is for components that are used many times in the app in a wide variety of contexts. When I first started migrating from MUI v4 to v5, I spent a decent amount of time figuring out the correct way to conditionally style components so I'll talk about that first.


⁠⁠⁠Conditional Styling

In MUI 4, conditional styling was done mainly by defining different class keys in an object and conditionally applying the class names like:

const useStyles = makeStyles(theme => ({
    paddingx: {
      padding: theme.spacing(0, 2),

    },
    nopadding: {
      padding: 0,
    },
}));

...
// I'm using clsx in the CustomComponent below but you can do something like:
// className={`${open && classes.paddingx}`}

const CustomComponent = () => (
  <div className={clsx({ 
    [classes.paddingx]: open, // If open is true, apply the paddingx styles
    [classes.nopadding]: isCompact // If isCompact is true, apply the nopadding styles
  })}>
     <SomeComponent />
  </div>
);


⁠Now, in MUI 5 there are a few different ways to conditionally style:

Using styled

1. Conditional Operator (Code Sandbox):

const StyledBox = styled(Box, {
  shouldForwardProp: (prop) => prop !== 'gutters',
})<StyledBoxProps>(({ theme, gutters }) => ({
  padding: theme.spacing(0, gutters ? 4 : 0),
}));

2. Short-circuit evaluation + Spread operator (Code Sandbox):

const StyledSpreadBox = styled(Box, {
  shouldForwardProp: (prop) => prop !== "gutters" && prop !== "dark"
})<StyledBoxProps>(({ theme, gutters, dark }) => ({
  padding: theme.spacing(4),
  border: "5px solid grey",
  ...(dark && {
    color: theme.palette.common.white,
    backgroundColor: theme.palette.primary.dark,
    borderColor: theme.palette.common.black
  })
}));


⁠Using sx

Code SandBox

<Box sx={{ px: gutters ? 4 : 0 }}>Content</Box>


⁠Breakpoints

If you're building a responsive website, there will be certain things that will have different styles depending on the media query breakpoints. Again, you can utilize either styled or sx


⁠Using styled

const StyledBox = styled(Box)<BoxProps>(({ theme}) => ({
  padding: theme.spacing(2),
  [theme.breakpoints.up('sm')]: {
    padding: theme.spacing(4),
  },

  [theme.breakpoints.up('md')]: {
    padding: theme.spacing(8),
  },
  [theme.breakpoints.up('lg')]: {
    padding: theme.spacing(12),
  },
  [theme.breakpoints.up('xl')]: {
    padding: theme.spacing(16),
  },
}));

...

<StyledBox>
  <CustomComponent />
</StyledBox>


⁠Using sx

<Box sx={{ p: { xs: 2, sm: 4, md: 8, lg: 12, xl: 16 } }}>
   <CustomComponent />
</Box>


⁠As you can see, sx is much more succinct especially if one of the shorthands like p for padding is being used. sx is pretty handy and there's a variety of ways to use it which mui has some good examples of here: https://mui.com/system/the-sx-prop/#responsive-values. In addition to the regular css properties and selectors, MUI has some custom properties and theme mappings like color: 'primary.main' which isn't quite the easiest list to find using their search. You can find that list here: https://mui.com/system/properties/


More Stories

Andrew Lai
Headless CMS with Next.jsMay 23, 2022
Cover Image for Headless CMS with Next.js

Integrating a content management system into a Next.js app


© 2022 nehno.com