reactjsnext.jssassmaterial-uicss-modules

Next.js module styles being over written by mui/material styles


I'm currently using next.js with scss modules for styling. I ran into a fun little problem with mui/material components. When running dev (npm run dev) everything works as expected. The fun starts when I ran this in production, my styles are being overwritten by what I think is emotion styled components from mui/material (I do not use the emotion library directly). My styles show below another class that is coming from an html style data-emotion tag. Now that I know this I can fix the styles by adding !important to my styles, but honestly I don't like that too much. Is there a way I can force my scss modules styles to always take priority? particularly for production?

Just to clarify, I'm just simply trying to adding margin, and in another instance change the color of a button. Here are my examples: Html:

<Typography variant="h5" className={styles.subtitle}>
  Hobbies and interests
</Typography>

Scss:

.subtitle {
  margin-top: 5rem;
  margin-bottom: 2rem;
  color: gray;
}

And for the button:

Html:

<Button
  className={styles.viewButton}
  variant="contained"
  >
  View gallery
</Button>

Scss:

.viewButton {
  margin-top: 5px;
  margin-left: auto;
  display: block;
}



Solution

  • The CSS injection order is causing the issue you are experiencing. In development, styles are injected in the same order that the component is installed. However, in production, styles are automatically extracted and injected at the top of the head element, which may result in styles being overridden unexpectedly.

    Material-UI uses the CSS-in-JS technique (emotion in v5, JSS in v4), which injects styles at the bottom of the head element and takes precedence over CSS module styling.

    i suggest to Create a Material UI theme:

    Use createTheme to create a Material-UI theme. Set disableServerRender: true for components to avoid server-side rendering.

    Wrap the Application with ThemeProvider:

    Import the ThemeProvider from Material-UI. Wrap your Next.js application with ThemeProvider and pass the produced theme.