Overview
Maintaining global CSS rules can be tricky. If you ever have to alter a CSS rule used by different HTML elements (or the React components that generate them), you have to make sure you don't accidentally change components that shouldn't change.
Build tools like Webpack allow you to use CSS Modules to locally scope your CSS and make it clear what components rely on what CSS. Once you have your build tools set up to use CSS Modules, it will process your class names to make them only apply to specific templates. Now you can easily update the CSS for a single component without worrying about changing components.
Using CSS Modules in an app created by Create React APP
If you want to use CSS Modules:
- Add
.module.css
to the end of your CSS file - Import that CSS file into your JS file
import styles from ./some-file-name.module.css
- Add the className prop to your component like this:
className={styles.someclassname}
If you use a class name in a component, and define it in your .module.css file, CSS Modules will change the names of both so they are locally scoped.
Example
If you have this in your component:
<img className={styles.someclassname} src={teaserImage} />
and .someclassname
is in your styles.module.css
file, the final HTML in your app will elements with your new locally scoped class
name like this
<img class="styles_someclassname__15W4Y" src="https://via.placeholder.com/150/9c9c9c/fff" />
Notice the pattern:
<css file name>_<original class name>_<generated hash>
Naming Classes: Using Hyphens or Dashes in Your Class Names
The maintainers of CSS Modules recommend using camelCase for your class names. However, you still use hyphens if you want. Because hyphens aren't allowed in JavaScript names, we have to tweak things a bit of you want hyphens/dashes in your class names.
You can alter how you access the value for your className property:
<img className={styles['some-class-name']} src={teaserImage} />
or, you can update your WebPack configuration, so it will transform your camelCased variable names to class names with dashes. Check out the Webpack docs about the CSS Loader configuration for some more information.
Naming Classes: You Can Use Shorter Class Names
Because you no longer have to worry about naming collisions, or losing track of what class applies to what HTML Element, you can use more minimal class names.
For instance, if you have a css module file named list-article.module.css
, your class names inside that file can
be more like .title
or .featuredImage
instead of .listArticleTitle
or .listArticleFeaturedImage
Multiple Classes On A Component
If you want to put multiple classes in the className
prop, you will be using some JavaScript. There are several
ways to do this, but they don't seem to be recommended.
Here is a way to do it with a template literal:
className='{${styles.someClass} ${styles.someOtherClass}}'
Composing Classes
One of the ideas behind CSS Modules is that each module has everything it needs to render an element, and you can do this using a single class. The problem here is that you can't just list out all the properties an element needs without duplicating code between elements. Eventually, you will need to share code.
In order have a single class completely describing an element and share code when appropriate, we can create our classes
using composes
. Make sure the composes rule are at the beginning of your rule.
@import 'someFile.scss';
.myClass {
composes: someClassFromTheFileWeImported;
color: black;
padding: 10px;
}
If you have more than one class to include via composes, you can have multiple composes
or mutliple classes in a
single composes
.myClass {
composes: someClassFromTheFileWeImported;
composes: differentClassFromTheFileWeImported;
color: black;
padding: 10px;
}
composes: someClassFromTheFileWeImported differentClassFromTheFileWeImported;
See Glen Maddern's article for a good explanation for using composition and CSS Modules
Sources
- Glen Maddern, "CSS Modules: Welcome to the Future," https://glenmaddern.com/articles/css-modules
- "Adding a CSS Modules Style Sheet," Create React App Documentation, https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/
- Robin Rendle, "What are CSS Modules and why do we need them?," CSS Tricks, https://css-tricks.com/css-modules-part-1-need/
- "CSS Modules Readme," https://github.com/css-modules/css-modules
- "Adding a CSS Modules Style Sheet," Create React App Documentation, https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/