rwparrish
Posted on November 8, 2020
Introduction
In my previous blog in this React series, I wrote about a couple of ways to style using CSS in React - stylesheets and inline styles.
Of course, those are only two of the many options available. I have recently played around with styled-components. I recommend trying out many different methods yourself to see which you prefer.
In this read, I want to do a short walkthrough on how to use CSS Modules. You can dive deeper into CSS Modules here.
Everything covered below will only work if you are using React scripts 2.X or higher. If you are using a lower version, you can still use CSS Modules but there are some extra steps involved that I will not cover here.
First, why use CSS Modules?
Well, there a few good reasons to check out this relatively new option for styling:
1. Separation of concerns - writing normal CSS code using CSS style sheets allows us to keep our JavaScript files (components in React) clean.
2. Scope - CSS Modules allow us to scope our style(s) to the component or element we want while keeping our CSS code in a separate file (separation of concerns).
3. Ease of use - once you understand how CSS Modules work, implementation is rather simple and the code is elegant.
Tutorial
To begin using CSS Modules with your fresh React app you will need to make use of the keyword module
in a couple of places:
import classes from './App.module.css'
some code...
In the import above notice module
in the syntax. Also, you will need to rename your CSS file. So, App.css becomes App.module.css. With this in place, the app is ready to be styled using CSS Modules. Let's examine the code.
In Person.module.css file:
.Person {
width: 60%;
margin: 16px auto;
border: 1px solid #eee;
box-shadow: 0 2px 3px #ccc;
padding: 16px;
text-align: center;
}
In Person.js (component) file:
import classes from './App.module.css'
const person = ( props ) => {
return (
<div className={classes.Person}>
<p onClick={props.click}>I'm {props.name} and I am {props.age} years old!</p>
<p>{props.children}</p>
<input type="text" onChange={props.nameChange} value={props.name}/>
</div>
)
};
Notice <div className={classes.Person}>
. Here, the imported JS object classes
has a Person
property. That property has an automatically generated CSS class mapped onto it. It looks something like Person__Person__ah5_1
.
Behind the scenes, React will automatically generate unique CSS class names for you. And by importing a JS object and assigning classes from there, you use these dynamically generated, unique names. So the imported JS object simply exposes some properties which hold the generated CSS class names as values.
Also, if you import the CSS file into a different component, the classes
object there will hold a Person
property which yields a different CSS class name - styling is scoped! Because you don't know what the behind-the-scenes generated CSS class name (string) is, you won't inadvertently use it to style another component.
One more thing. If instead you actually want to be able to use a CSS class defined in a .module.css
file anywhere in your app and receive that styling (avoid the uniquely generated class names), you can prefix the selector with :global
.
Example:
:global.Person {
width: 60%;
margin: 16px auto;
border: 1px solid #eee;
box-shadow: 0 2px 3px #ccc;
padding: 16px;
text-align: center;
}
Recap
With CSS Modules, you can write normal CSS code and make sure that it only applies to a given component. I also prefer using this method because it keeps my JS files from becoming cluttered.
It is my hope that you learned something. As always, ask questions, leave feedback, and keep on coding!✌️
Posted on November 8, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.