The combination of CSS Modules and PostCSS could be our new option
As a junior front-end developer I was using Sass for my entire career. Sass is super easy to write and it has many features which makes our front-end development more scalable, efficient and most importantly enjoyable :)
But recently more and more developers are considering CSS Modules or PostCSS in their products. That makes me curious about new way to style our product.
Unfortunately Sass is based on ruby. If we are on Ruby on Rails, Sass seems to be natural way for styling. Sprockets kindly deals with it instead of us. But what if we create our application by pure front-end stacks like React.js, Angular.js, Vue or Amber. We have to prepare gulp or grunt or something to convert Sass into CSS.
And secondly Sass seems to be “All in one” tool. Do we really need mixins or varibles in our every single application we create? After looking back to my career, I realized that only a few features like nesting or import are nessecary for styling.
So I tried CSS Modules and PostCSS in our product lately. Here is my impression about them and way to do it.
CSS Modules
I guess many developers already know CSS Modules. It’s kind of CSS in JS.
Here is a list of options which make CSS available in JavaScript.
And here goes an amazing post about comparison of CSS in JS and CSS Modules.
At Buffer, we love React and are incrementally moving a lot of our front-end codebase to it. With Flux on top of it, we…medium.com
CSS in JS and CSS Modules are different in the point of how CSS exists. In CSS in JS world, CSS is written in JavaScript Object. It’s like immetation of <style />. By using CSS loader of Webpack we can import suchCSS-like objects into JavaScript. And styles are added as JSX’s inline style.
Yeah, that works! But I prefer CSS Modules because it creates whole new CSS files. Yes, we have to add one more <link /> to include CSS file — one more HTTP request. But it’s not inline styles anymore, which means that pseudo classes or media queries are available. This is a good news, isn’t it?
And the biggest benefit we can take is that CSS class names will be local scoped by using CSS Modules.
Let me show you code example and how it works later.
PostCSS, cssnext
So we decided to use CSS Modules. It’s not something like CSS-like objects. Row usual lovely CSS files. But some problems here. It’s CSS not Sass, so we can’t use nesting or import as natural.
Solution is PostCSS — more precisely, cssnext.
PostCSS is useful tool with many libraries like postcss-autoreset ,postcss-sorting and so on.
But to be honest I still don’t fully understand that usufulness. Because we decided to set standard for what we use. We are seeking features which are truly nessecary. Once installing as many PostCSS libraries as possible, it’s nothing but Sass. So this time we use only postcss-cssnext plugin.
Postcss-cssnext plugin is a converter for cssnext.
postcss-cssnext - :cyclone: PostCSS plugin to use tomorrow's CSS syntax, today.github.com
CSS next is a set of CSS features that is highly likely to be supported in the browsers in the near future.
Prior to 2015, CSS was frustrating by not having any specification for features we were looking for. No variables, no…cssnext.io
The relationship between Postcss and cssnext is similar to the one between ES201* and Babel — Future language set and Transpiler.
Plan is ready, but how?
OK! Now we only use pure CSS with latest CSS features. It’s because of combination of CSS Modules and PostCSS.
But there’s no actual codes yet at all. From now description in detail starts.
packages
Here is a list of all packages for CSS Modules and Postcss.

We use Webpack and Babel as Front-end environment.
Config for CSS Modules
Ok, we have packages now. Let’s set up configuration for CSS Modules.
This is a partial of our webpack.config.js.
All we have to do is turing on Modules mode of css-loader by adding ‘modules’ query.
But this makes JavaScript create <style /> dynamicaly. So unfortunately there is a possibility to generate lag when rendering.
So we need to do one more thing. By using ExtractTextPlugin Webpack can generate new CSS file. It’s totally static and HTML can read it before rendering DOMs. No styling lag.
This config above means Webpack generates application.css.
And here is a CSS file we create and import in JavaScript.
And this is a React component of Button.
Styles can be accessed by hogeStyle.hoge.
But acctualy buttonStyle.button is like “.3d1CM”.
CSS class name is converted into Hash value that prevents from naming conflicts. So CSS is scoped locally by using CSS Modules.
application.css converted from button.css is like below.
And button.js component is converted like below.

Can you see that classname are match between CSS and HTML.
Converted classname is hash value. But we don’t have to care about it. Webpack, css-loader, ExtractTextPlugin take care of it instead of us.This is super easy, isn’t it??
Configure for PostCSS
OK, this time let’s add some lines in webpack.config.js.
We added two new things here.
One is adding ‘postcss’ loader after css-loader. To integrate them together importLoaders query for css-loader is necessary.
And another is postcss item for webpack config. And in postcss item we defined to use postcss-cssnext plugin.
That’s it! We can use cssnext in our CSS files now.
For example nesting is one of cssnext features. We add :hover style for Button.
This will be converted like below.
Postcss-cssnext plugin solves nesting into plain CSS.
css-loader queries
The basic explanation of CSS Modules and PostCSS is over. From now let’s take a look at some tips.
I know some people don’t like string query for webpack loaders. We can define queries separately like below.
Yeah, it looks smarter. But unfortunately ExtractTextPlugin.extract function return loaders. Not singular. We can’t use query key for multile loaders.
So as a workaround I defined queries before configs.
Got better I guess.
Other css-loader options
The css-loader has other options. Here is sample queries we use in our production.
camelCase is so usuful. We prefer class names chained by hyphens like ‘hoge-container’. But you know we can’t use that case in JavaScript. So camelCase option makes css-loader convert case of class names.
As you can imagine sourceMap enables us to see sourcemap.
localIdentName is option to determine the form of converted class name. As default in CSS Modules’ world class names will be converted to only hash values. But this is not good for humans. By configuring like above converted class names will be like ‘button-primary-2N09e’. [name] means CSS file name, [local] is class name and [hash:base64:5] is hash value.
Conclusion
To use CSS Modules and PostCSS we have to do some setups as you see in this post. And knowledge about webpack or npm is required. Plus so far I couldn’t find other way to do this but webpack. Dependency on Webpack may be too strong? Some developers doesn’t accept this, I know.
But CSS Modules and PostCSS together could be the one of options to style, like Sass is. I reccomend Front-end developers to know there is a option like this and try it at least once. But for Server-side developers and Designers who write CSS it’s bit hard to spend their time on learning them…
So important thing is “Don’t rely on Sass with no considering. Consider and have conversation in your team if CSS Modules and PostCSS can suit in your product”.
Sample codes are in my Github repo.
Contribute to learning-langs development by creating an account on GitHub.github.com
Please check it for full files.
CSS Modules or PostCSS references
http://glenmaddern.com/articles/css-modules
https://medium.com/@pioul/modular-css-with-react-61638ae9ea3e#.blpcd13lf