What is CSS Module?

What is CSS Module?

How CSS Module Work

ยท

8 min read

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>
    </>
  );
};

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>
    </>
  );
};

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;
}

in ComponentTwo > style.css

.heading {
  color: red;
}

.sub-heading {
  color: blue;
}

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>
  );
}

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
  }
  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
  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

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;

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

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;
}

Example:

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

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;
}

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;
 }

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;
 }

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;
 }

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;

style.module.css

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

 .heading {
   color: blue;
 }

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...

Thanks,
CapsCode

Did you find this article valuable?

Support CapsCode's Blog by becoming a sponsor. Any amount is appreciated!

ย