My journey from CSS Modules to CSS-in-JS

I recently started a React + Material-UI project. I naturally chose CSS modules (SASS modules to be exact) for styling over CSS-in-JS because I was more familiar with CSS/SASS. I also added typings-for-css-modules-loader in Webpack config for adding typing in TypeScript.

Then I started to realize a few issues.

For example, Webpack will generate .d.ts file automatically, but not that reliable. Sometimes I need to go back and forth and save (which triggers compiling and hot reloading) the component file itself, the component file which imports this component, and the CSS file.

But one other issue raises the red flag for me: customizing/overriding MUI styling is painful using CSS Modules.

For example, I have a simple icon button, but I need it to be smaller than the MUI default. And this is the code:

See those !important ? My styles won’t work without it. Why? Because MUI styling somehow has higher precedence. And sometimes it begins a guessing game, should I add or not?

padding and colour of `button` get overridden

I was told there might be a solution from Webpack config but I’m not comfortable messing with Webpack. So if anyone has any suggestions and example, I’m happy to listen.

So I go back to the beginning. I chose CSS because I’m more familiar with it. This is so NOT ME. I should not be afraid of trying new things.

I started some research on CSS-in-JS. Well, it didn’t take long, because Material-UI core styling is using JSS. The dependency is built-in so there is no additional bundle size overhead. Furthermore, I have already used some JSS for overriding the MUI theme globally in the code. Although there might be more popular or powerful CSS-in-JS libraries, using JSS here should be the first choice.

Then I re-wrote the component:

That’s it. All in one file. And it works without !important.

So let’s compare. I basically copy the stylesheet to .tsxfile. There is a bit of work (and a bit learning curve) but the idea is simple: 1) convert the CSS keywords from kebab-case to camelCase, 2) add a quote to CSS values, or make pixel value a number without “px”.

There are different ways to utilize JSS in the component but since I’m using Material-UI, I use makeStylesto get a hook and then get the classes inside the functional component.

In short, I like my new choice: everything is JavaScript and is in one file (if you say the file will get too big, then I’ll argue you should break your component into smaller pieces); no more guessing game with !important; no need to deal with CSS typing.

And more studies came

The above example code shows how to use JSS in React functional component, but it won’t work with the React class component, because makeStyles generates a hook, which can only be called inside a functional component. So how to use JSS for the class component?

The code can be rewritten into this:

It is using MUI’s withStyles instead. It is a HOC (Higher-Order Components) rendering custom component with custom styles. It’s not bad either!

So what else can I use in JSS? First I tried the pseudo-class. Instead of using MUI IconButton , I just simply tried a div :

Voila! Next, nested class:

Yep, also straightforward.

Any comments or suggestions are welcome! Peace out!

A digital poet, casual gamer, ex-YouTuber, baseball fan, Dr.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store