DEV Community

Cover image for What is CSS Module?
capscode
capscode

Posted on • Originally published at capscode.in

What is CSS Module?

Table of content

  1. Introduction
  2. What is CSS Module
  3. How to use CSS Module
  4. How to write multiple class name in CSS Module
  5. Gloabel styling in CSS Module
  6. Styling HTML element in CSS Module
  7. Compose in CSS Module
  8. Variable in CSS Module
  9. How CSS Module work
  10. Conclusion

1. Introduction

CSS modules are just like plain CSS which you already know with lots of extra advantages and some specific rules.

2. Why we are using CSS modules and what is the need to use them?

If you have worked in ReactJS for creating your web apps, then you might be aware that all of the CSS files in your application are combined and get added to the style tag of your document (at the top).

image of map files

Due to this, the styles of the classes get overridden and you may get some styling issues in the application.

NOTE: The overridden depends on the import of the component and most last import will override the previous ones.

Example,
let's say we have two components folder

  1. ComponentOne
    1. index.js
    2. style.css
  2. ComponentTwo
    1. index.js
    2. style.css

and we have h1 tag with classname heading, h2 tag with classname sub-heading in both ComponentOne & ComponentTwo.

ComponentOne.js

import "./style.css";
export default CompOne = () => {
  return (
    <>
      <h1 className="heading">Component One Heading--green</h1>
      <h2 className="sub-heading">Component One Subheading--yellow</h2>
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

ComponentTwo.js

import "./style.css";
export default CompTwo = () => {
  return (
    <>
      <h1 className="heading">Component Two Heading--red</h1>
      <h2 className="sub-heading">Component Two Subheading--blue</h2>
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

We have given color styles to both tags in their respective style.css file and import them in their respective component file.

in ComponentOne > style.css

.heading {
  color: green;
}

.sub-heading {
  color: yellow;
}

Enter fullscreen mode Exit fullscreen mode

in ComponentTwo > style.css

.heading {
  color: red;
}

.sub-heading {
  color: blue;
}
Enter fullscreen mode Exit fullscreen mode

and we are importing both the components in App.js

import ComponentOne from "./ComponentOne";
import ComponentTwo from "./ComponentTwo";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <ComponentOne />
      <ComponentTwo />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Please take note that we have imported ComponentTwo after importing ComponentOne
and below is the output

image of map files

What happened here is that the ComponentTwo style.css has taken priority and its style has overridden the style of ComponentOne folder's style.css.

What if we import ComponentTwo before ComponentOne?
image of map files

Have you noticed the difference?
What happened here is the ComponentOne style.css has taken priority and its style has overridden the style of ComponentTwo folder's style.css.

And that's the biggest issue when multiple developers work on the same project and are giving the same classname to the elements.

This is one of the main reasons we should use CSS Module in ReactJS.

No one wants to clutter their code with !important overrides in CSS as it creates a lot of confusion while debugging. However, !important becomes tempting as the project grows and multiple developers work in a team. CSS Modules are one way to solve this issue.

3. How to use CSS Module in RectJS

  1. Instead of creating the file as filename.css you have to create the file as filename.module.css

style.module.css

  .header{
      font-weight:700;
      color:red;
  }
  #sub-heading{
      color: black;
      background-color:white
  }
Enter fullscreen mode Exit fullscreen mode
  1. We have to then import these CSS Module styles into a variable and that variable (let's say styles) will be a JavaScript object containing all the styles (classes, ids).
import styles from './style.module.css
Enter fullscreen mode Exit fullscreen mode
  1. Then wherever you are writing your classNames you have to write them like
<h1 className={styles.heading}>Heading</h1> //adding className

<h2 id={styles["sub-heading"]}>Sub Heading</h2> //adding id
Enter fullscreen mode Exit fullscreen mode

We can also destructure the class names and id names.

import {heading, "sub-heading" as subheading} from './style.module.css'

// or

let { heading, "sub-heading": subheading } = styles;
Enter fullscreen mode Exit fullscreen mode

Do you know why we have assigned new names to the "sub-heading" key ?
check out here

NOTE: All the rules for accessing classes/ids from CSS Module will be similar to accessing keys in JS objects.
As we know that the id's should be unique in the html document, whenever we give styling to the id it will get applied to that element but in CSS Module compiler used to generate a unique name for all the classes and id's defined in the CSS Module and hence the same id name in multiple CSS Module files get different name during build time.

That's it, you are done. CSS Module is as simple as CSS is.

Let's see some of the important points of CSS Module (how to...).

4. How to write multiple class names to an element when we are using CSS Module

we can use the JSX syntax to write that

<div className={`${styles.heading} ${styles.mainHeading}`}>Heading</div> //adding multiple className

// OR

<div className={styles.heading +" "+ styles.mainHeading}>Heading</div> //adding multiple className
// not preferable
Enter fullscreen mode Exit fullscreen mode

5. How can we make a global styling in CSS Module

We just need to add :global suffix before the defined classname in the CSS Module.

Syntax

:global (.myclass) {
  background-color: red;
}
Enter fullscreen mode Exit fullscreen mode

Example:

:global .global-style {
    color:cyan
}
Enter fullscreen mode Exit fullscreen mode
<h3 className="global-style">Component Heading</h3>
Enter fullscreen mode Exit fullscreen mode

6. We should not give styling to the elements in CSS Module.

We should never apply CSS to an HTML element in the CSS Module because if we do so, then it will become the global one automatically.

h3 {
  font-size: 20px;
  font-style: italic;
}
Enter fullscreen mode Exit fullscreen mode

Best practice is to create some global css file (let's say global.css) file and define all your global styling in that file.

7. Composing multiple styles together in CSS Module.

You can create a class and then compose it within other classes by using the composes selector.

 .heading {
   background-color: green;
   color: white;
 }

 .main-heading {
   composes: heading;
   color: blue;
 }
Enter fullscreen mode Exit fullscreen mode

The classes being composed do not have to be in the same file. It can be imported in from another css file or module as well.

 .main-heading {
   composes: heading from './style.css';
   color: blue;
 }
Enter fullscreen mode Exit fullscreen mode

8. How to define CSS variables in CSS Modules.

CSS Modules have a variable system that allows you to create variables in the CSS Module.

@value blue: #ff0000;
@value red:#0c77f8;
@value green: #aaf200;

/* Note that we have given some red kind of color code in blue variable */
 .heading {
   color: blue;
 }
Enter fullscreen mode Exit fullscreen mode

In the example above, we've created valriable blue, red and green. For cleaner referencing and reusability, these values can be defined in a separate file and then we can imported from there.

colors.css

@value blue: #ff0000;
@value red:#0c77f8;
@value green: #aaf200;
Enter fullscreen mode Exit fullscreen mode

style.module.css

 /* importing variable. */
@import colors: "./colors.css";
@import blue, red, green from colors;

 .heading {
   color: blue;
 }
Enter fullscreen mode Exit fullscreen mode

NOTE: in some of the documents you may see @value in place of @import. Both are fine, it depends on the compiler.

Please checkout the codesandbox for the css module example

9. How CSS Module works behind the scene

CSS Modules create a unique classname of the format [filename]_[classname]__[hash].

When we import our CSS Module, CSS module export the classnames and ids defined in the file like a normal JavaScript object,
where the keys will be the original classnames/ids (only name) and their value will be the globally generated classes and ids (generated by webpack or any other compiler in the format mentioned above)

The build tools transform our class names into variables that are exported separately as named exports and as an object.

Although CSS Module is written like plain CSS, it actually compiles to a low-level interchangeable format called ICSS (Interoperable CSS) that is designed for loader implementers, not end-users. It is a superset of standard CSS and a low-level file format that enhances CSS.

Tools such as Webpack are used to perform this compilation process.

Also, if you import the CSS file into a different component, the key names would also be different as its locally scoped and the compiler would be named in the format of [filename]_[classname]__[hash]

You may have some questions in your mind that how it is getting exported from filename.module.css
It's as simple as exporting object from JavaScript.

This image speaks 1000's of word.
image of map files

Please double-check the point 1. and point 2. marked in the image.

if you want to check the demo of how css module does the export of styles, do cehckout

10. Conclusion

Awesome! Now you become an expert in using CSS Modules in your application.
CSS module are very much useful when you dont want to install any 3rd party library like StylesComponent, Emotions etc. and want to continue writing your CSS in the tradtional way.
Its developer friendly, less time consuming, easy to debug and easy to manage as well.

Thank you for reading this far. This is a brief introduction of CSS Module.

If you find this article useful, share this article. Someone could find it useful too. If you find anything technically inaccurate please feel free to create a issue.

Hope it's a nice and informative read for you.
VISIT https://www.capscode.in/blog TO LEARN MORE...

Few of the trending articles,

Thanks,
CapsCode

Top comments (8)

Collapse
 
monfernape profile image
Usman Khalil

Amazing

Collapse
 
capscode profile image
capscode

Thanks, i hope this will be helpful for you next project.
Stay tuned.

Collapse
 
jeancho profile image
Hyejin Cho

Amazing post!

Collapse
 
capscode profile image
capscode

Thank you 🙂🙏

Collapse
 
zyahya profile image
Ziad Yahya

Good work 👏

Collapse
 
capscode profile image
capscode

Thank you.
:)

Collapse
 
dumebii profile image
Dumebi Okolo

Great! I haven't used CSS modules in a while because I now use Tailwindcss heavily.
But this was a great refresher and learnt some new things as well.

Collapse
 
capscode profile image
capscode

Thanks a lot, Glad you liked it and you learnt from this article.
:)