Styling with CSS Modules

Let's cover styling in more depth.

In a previous article, we touched briefly on styling JSX using inline styles and with CSS.

One of the strengths of React.js is its component-based architecture, which enhances code reusability and separation of concerns.

However, when styling these components, things can get tricky when using global stylesheets and writing CSS inline as JavaScript.

This is where CSS modules come into play.

Styling with CSS Modules

What are CSS Modules?

It's a way to use CSS in your JavaScript, where class names become unique per component.

When we use CSS modules, the styles defined in that CSS module are scoped to the component and will not affect other parts of your application.

You don't have to worry about naming collisions or specificity wars in your CSS. 🎉

Here's a short example to see it in example:

/* MyComponent.module.css */
.title {
  color: red;
// MyComponent.js
import styles from './MyComponent.module.css';

const MyComponent = () => (
  // We refer to the styles via our import 👇
  <div className={styles.title}>This text will be red!</div>

export default MyComponent;

In this example, the title class in MyComponent.module.css is scoped to the MyComponent component.

Even if you have another title class in a different CSS Module, it won't affect the styling of MyComponent.

This scoping is achieved by CSS Modules automatically generating unique class names when you build your application.

So in the generated HTML, the class name might look something like this: title_1a2b3c, which is unique and specific to that component.

In Vite, my rendered HTML looked like this:

<div class="_title_11mo7_1">This text will be red!</div>

Benefits of CSS Modules

  • Local Scope: By default, all styles in a CSS Module are local to the component, significantly reducing the possibility of conflicts.
  • Code Splitting: Since your styles are now tied to your components, they can be split and loaded on demand, just like your JavaScript. This could lead to performance improvements.
  • Easier Maintenance: With CSS Modules, tracking which styles are used in your application and which can be deleted is easier. This makes maintaining your CSS much more manageable.

Integrating CSS Modules in React

If you're using CodeSandbox, Vite, Next.js, or Create React App (CRA), or even a build tool like Parcel the good news is: CSS Modules are supported out of the box. 📦

All you need to do is to use the .module.css extension instead of the regular .css when creating your CSS file.

Then as you saw in the previous example, you import the value as an object and start using it in your className.

Using Multiple Classes

When using CSS Modules in React, there may be instances where you want to apply multiple classes to a single element. This wasn't obvious to me when I started using CSS modules.

This can be achieved by using JavaScript's template literals:

// MyComponent.js
import styles from './MyComponent.module.css';

const MyComponent = () => (
  <div className={`${styles.classOne} ${styles.classTwo}`}>
    I use multiple styles

export default MyComponent;

CSS Modules can help you write cleaner, more maintainable CSS by ensuring that all styles are local to the component.

But remember, while CSS Modules are a great tool, they are not the only way to style React components!

I introduced this concept since it's one of the most common ways to style React applications without introducing more libraries.

In our next and final article, we will combine everything we have learned into a final project.

I'll link it here when it's done.

Follow me on Twitter or connect on LinkedIn.

🚨 Want to make friends and learn from peers? You can join our free web developer community here. 🎉

Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses; Lead Developer, Software Architect, Product Manager, CTO and now happily a Founder.


Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.