Choosing CSS approach for greenfield React website

Adam Brodziak
3 min readApr 15, 2016
  1. The case: I have to make a decision for a CSS approach for a new website (not SPA!) build with React.
  2. The problem: I was out of frontend development for years. To give an impression I haven’t got chance to use LESS, because it was not there yet.
  3. The status: sooo many options! Dwelling into new ways of handling styles and CSS just adds to the JavaScript fatigue caused by React already, but I digress.

Some time ago I’ve stumbled on Why You Shouldn’t Style React Components With JavaScript which talks why inline styles promoted by some React tutorials are bad. To make things better James have built react-pacomo library that creates class prefixes in CSS automatically (similar to BEM, but simpler, see FAQ). Prefixing CSS class names worked last decade and I’m keen admirer of James work, so it seemed like a good start. Then I’ve found James comment about CSS Modules on Github, which basically states: “if you need performance or are writing a complex app, CSS Modules are a better pick”. Oh gosh, CSS Modules?

Actually BEM (Block-Element-Modifier) seems pretty decent methodology of writing scoped CSS. It requires to follow convention of using long class names like “block__element — modifier” which some people find ugly. Well, definitely if you have to write it by hand. Anyway, the approach fits nicely with the global nature of CSS and the fact most likely you’ll have one big CSS file with all rules. Also similar thing worked for me in the past, but world has moved on and I’m going to write small React Presentation Components, not bulky pages. We can do better. Bonus point: it comes from Russians and things coming from Russian people are cool :)

This brings be back to CSS Modules. BTW: their logo is awesome! Glenn Maddern, the creator of CSS Modules, addresses my issue with long class names and global scope in Step 1 of his excellent CSS Modules. Welcome to the Future article. Sure, you end up with even longer class names in the browser, but the Interoperable CSS standard was never meant to be written nor consumed by humans.

Going further CSS Modules approach wins me over with the notion of single responsibility modules that are separated in their own files and the ability to compose those. It really looks like a semantic expression of a visual component, rather than just its theme or looks. Go look at the examples in the article, especially the one about React component. Of course there’s npm package with React CSS Modules integration ready to use!

Does it means it’s all roses with CSS Modules? Not really, as Francois Ward mentiones in State of the Art JavaScript in 2016 that Webpack css-loader is slow with CSS Modules enabled. Indeed I’ve found performance regressions reported, probably caused by switching to PostCSS (more on PostCSS later!) processing in css-loader Webpack plugin. Not a surprise given that it’s complex piece of code, which is typical to parsers and text processors.

That leaves me with PostCSS, which was also recommended, even in addition to other CSS processors. Frankly I don’t know how to position PostCSS, but it seems to be lower level tool to handle plain CSS. Or maybe it’s more of a framework to build other CSS tools, like CSS Modules mentioned above or Autoprefixer? This way or another it seems something to keep my eyes on, since it’s going to show up anyways. I guess more reading ahead of me: What PostCSS Really Is; What It Really Does

Not much to talk about LESS or SASS. I consider them tools from previous generation. Their main focus was to address CSS shortcomings, like lack of variables in CSS (CSS variables are coming I know). LESS and SASS, similarly to BEM, are doing excellent job in a paradigm of global CSS where cascade can bite ou hard, variables do not exist and you never delete CSS code. I’m looking at paradigm shift where you write independent React components that are self-contained (along with its styling).

That’s it in terms of getting over CSS novelties for now. It was great exercise to wrap my head around that topic and write it up here for clarity and future reference. Nothing conclusive as of now, as the decision process continues. Any feedback, comment or suggestion? Leave a comment or ping me on Twitter, please.