Using CSS Modules with React

A quick overview of what is CSS Modules, how it works, how it’s used together with React, plus some useful tips

Image for post
Image for post

What is CSS Modules?

A CSS Modules is a CSS file in which all class names and animation names are scoped locally by default.

CSS Modules is not an official specification nor a standard. It’s a sort of step in the CSS/JavaScript building process, which modifies CSS classes by appending some unique hash, thus ensuring, that your CSS styles are locally scoped and don’t overlap with each other.

How does CSS Modules work?

Your original CSS file will be compiled into a special ICSS (Interoperable CSS) format, which outputs CSS styles and JavaScript Object.

  • CSS styles: compiled CSS with modified class names.
  • JavaScript Object: used to map original class names to modified class names.

Most of the module bundlers, such as webpack, parcel etc support CSS Modules through plugins or loaders.

Also, create-react-app supports CSS Modules out of box.

Example:

See, how original class name .container was renamed to a .styles_container_g2x5j , in order to scope CSS locally and avoid class name conflicts.

Note: .styles_container_g2x5j is just an example.
It’s possible to configure CSS modules compiler class name generation pattern/function.

Using with React

Using CSS Modules in React is really straight forward.

Probably, you’ve already noticed that multiple and conditional class names don’t look nice, and seem to a bit overcomplicated.

One way to solve this is to create some utility functions to work with styles object.

However, there’s already such npm package called classnames.

So far when using classnames npm package code looks much better.

However, it’s still a bit different from what just regular HTML/CSS classes look like when we just write <div class="foo bar">...</div> .

There is babel-plugin-react-css-modules that brings back that functionality into CSS Modules. With this plugin enabled, we can provide original class names to a special styleName attribute and the plugin replaces them with modified class names during build time.

In short, babel-plugin-react-css-modules transforms styleName to className using compile time CSS module resolution.

Conclusion

CSS Modules and React plays very well and, most importantly, solves the issue of having global styles and class name overlapping, while keeping CSS and JS separate.

However, there is another approach for creating locally scoped styles, which is called CSS in JS. There are plenty of implementations/libraries of CSS in JS such as styled-components, emotion, JSS, etc. The choice between CSS Modules and CSS in JS is a matter of preference of a developer or team, and of course, consistency within a project.

We have launched three new publications! Show some love for our new publications by following them: AI in Plain English, UX in Plain English, Python in Plain English — thank you, and keep learning!

We are also always interested in helping to promote quality content. If you have an article that you would like to submit to any of our publications, send us an email at submissions@plainenglish.io with your Medium username and we will get you added as a writer. Also, let us know which publication/s you want to be added to.

Sr. Software Engineer

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