Andrew McKeever
Posted on January 15, 2020
Breaking larger code bases into smaller chunks using component based architecture has made it much easier for us developers to architect a clean project; it can even improve productivity. However, one of the biggest challenges in creating unique names for all of these components, since many of them tend to function similarly or are the same type with a few style modifiers. This overlap can cause a huge mess in our CSS. The popular solution to this problem has been to use CSS in JS and many libraries have been built each with their own take on how to do it. However, plain CSS offers a solution with a simple amount of configuration, allowing us to avoid depending on a library.
Why use CSS Modules?
The main benefit of CSS modules is that classes are locally scoped. Every classname generated in a CSS file will have a unique name given to it at build time. How is this handled? Well we will need to set up Webpack to do this for us, but don't worry it's not too bad.
If you're used to using naming conventions like BEM to prevent class styling overlap, you'll know that classnames can become incredibly long. This makes it harder to read your code and really know which styles am element is receiving from which modifiers. With CSS modules, you can drop naming conventions as you only have to worry about unique names inside of the locally scoped file(e.g. two elements in separate JS and CSS files can have the same name).
How to get started.
Getting started doesn't require too much setting up, but can be a little confusing if you're unfamiliar with Webpack. However, even if you've got very little experience it's one of the easier configurations to get working. We'll need to install the css-loader
package from npm
to use it in our webpack.config
file.
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: 'css-loader',
options: {
modules: true,
},
},
],
},
};
Here we're telling Webpack to use css-loader
to handle all files with the CSS extension. From there we just set the module option to true and that's it! Pretty straight forward.
Once we've configured Webpack we're ready to get started. We can create our style sheet like we normally would; we'll create a styles.css for this example.
.someComponent {
width: 100%;
height: 250px;
background-color: #ebebeb;
}
Then we import simply import our style sheet into our JS file.
import style from './styles.css'
component.innerHtml = `<div class={style.someComponent}>I'm using CSS modules></div>`
As mentioned, CSS modules will become locally scoped. Our output then at build time will look something similar to this
html
<div class="style_someComponent__3N3nB">I'm using CSS modules</div>
css
.style_someComponent__3N3nB {
width: 100%;
height: 250px;
background-color: #ebebeb;
}
That's all there is to it! We can now easily prevent any stylings from overriding components where they shouldn't without changing much at all on how we style our html.
Posted on January 15, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.