CSS modules provide a way to locally scope CSS class names. You don’t have to worry about overriding styles when you use the same class name.

Find out how CSS modules work, why you should use them, and how to implement them in a React project.

What Are CSS Modules?

The CSS modules docs describe a CSS module as a CSS file whose class names are locally scoped by default. This means you can address CSS variables with the same name in different CSS files.

You write CSS module classes just like normal classes. Then the compiler generates unique class names before sending the CSS to the browser.

For example, consider the following .btn class in a file called styles.modules.css:

        .btn {
    width: 90px;
    height: 40px;
    padding: 10px 20px;
}

To use this file, you have to import it into a JavaScript file.

        import styles from "./styles.module.js"

Now, to reference the .btn class and make it available in an element, you would use the class as shown below:

        class="styles.btn"

The build process will replace the CSS class with a unique name of the format like _styles__btn_118346908.

The uniqueness of the class names means that, even if you use the same class name for different components, they will not collide. You can guarantee greater code independence since you can store a component’s CSS styles in a single file, specific to that component.

This simplifies debugging, especially if you are working with multiple stylesheets. You’ll only need to track down the CSS module for a particular component.

CSS modules also allow you to combine multiple classes through the composes keyword. For example, consider the following .btn class above. You could “extend” that class in other classes using composes.

For a submit button, you could have:

        .btn {
    /* styles */
}
 
.submit {
    composes: btn;
    background-color: green;
    color:#FFFFFF
}

This combines the .btn and the .submit classes. You can also compose styles from another CSS module like this:

        .submit {
    composes:primary from "./colors.css"
    background-color: green;
}

Note that you must write the composes rule before other rules.

How to Use CSS Modules in React

How you use CSS modules in React depends on how you create the React application.

If you use create-react-app, CSS modules are set up out of the box. However, if you are going to create the application from scratch, you will need to configure CSS modules with a compiler like webpack.

To follow along with this tutorial, you should have:

Creating a React Application

To keep things simple, you can use create-react-app to scaffold a React app.

Run this command to create a new React project called react-css-modules:

        npx create-react-app react-css-modules

This will generate a new file called react-css-modules with all the dependencies required to get started with React.

Creating a Button Component

You will create a Button component and a CSS module called Button.module.css in this step. In the src folder, create a new folder called Components. In that folder create another folder called Button. You will add the Button component and its styles in this folder.

Navigate to src/Components/Button and create Button.js.

        export default function Button() {
    return (
        <button>Submit</button>
    )
}

Next, create a new file called Button.module.css and add the following.

        .btn {
    width: 90px;
    height: 40px;
    padding: 10px 20px;
    border-radius: 4px;
    border: none;
}

To use this class in the Button component, import it as styles and reference it in the class name of the button element like this:

        import styles from "./Button.module.css"
 
export default function Button() {
    return (
        <button className={styles.btn}>Submit</button>
    )
}

This is a simple example that shows how to use a single class. You may want to share styles across different components or even combine classes. For this, you can use the composes keyword as previously mentioned in this article.

Using Composition

First, modify the Button component with the following code.

        import styles from "./Button.module.css"
 
export default function Button({type="primary", label="Button"}) {
    return (
        <button className={styles[type]}>{label}</button>
    )
}

This code makes the Button component more dynamic by accepting a type value as a prop. This type will determine the class name applied to the button element. So if the button is a submit button, the class name will be “submit”. If it is “error”, the class name will be “error”, and so on.

To utilize the composes keyword instead of writing all the styles for each button from scratch add the following to Button.module.css.

        .btn {
    width: 90px;
    height: 40px;
    padding: 10px 20px;
    border-radius: 4px;
    border: none;
}
 
.primary {
    composes: btn;
    color: #FFFFFF;
    background-color: #6E41E2;
}
 
.secondary {
    composes: btn;
    color: #6E41E2;
    background-color: #FFFFFF;
}

In this example, the primary class and the secondary class utilize the btn class. By doing this, you reduce the amount of code you need to write.

You can take this even further with an external CSS module called colors.module.css, containing the colors used in the application. You could then use this module in other modules. For example, create the colors.module.css file in the root of the Components folder with the following code:

        .primaryBg {
    background-color: #6E41E2
}

.secondaryBg {
    background-color: #FFFFFF
}
 
.primaryColor {
    color: #FFFFFF
}

.secondaryColor {
    color: #6E41E2
}

Now in the Button/Button.module.css file, modify the primary and secondary classes to use the above classes like this:

        .primary {
    composes: btn;
    composes: primaryColor from "../colors.module.css";
    composes: primaryBg from "../colors.module.css";
}
 
.secondary {
    composes: btn;
    composes: secondaryColor from "../colors.module.css";
    composes: secondaryBg from "../colors.module.css";
}

Sass With CSS Modules

You can use CSS modules to improve the modularity of your codebase. As an example, you can create a simple CSS class for a button component and reuse CSS classes through composition.

To power up your use of CSS modules, use Sass. Sass—Syntactically Awesome Style Sheets—is a CSS preprocessor that provides a ton of features. They include support for nesting, variables, and inheritance that are not available in CSS. With Sass, you can add more complex features to your application.