CSS-in-JS for your React app

CSS-in-JS has been one of the biggest developments of the past few years in the CSS world. Just like preprocessors bypassed CSS to introduce their own set of new features over a decade ago, CSS-in-JS libraries piggyback on JavaScript's power to make their own path without waiting for CSS to catch up.


For a long time, writing CSS was straightforward: add .css extension to your file, open up a text editor, and start typing. Over the years, CSS has developed its own ecosystem of technologies, from preprocessors like Sass and Less to methodologies like BEM, to more recent developments like CSS-in-JS.

CSS-in-JS represent a collection of ideas to solve complex problems with CSS. It's NOT a particular library, there does exist different libraries to choose and, they all may solve a different subset of problems and use different approaches, depending on their implementation details.

However, all implementations have in common that they tackle the problems using APIs instead of convention and, they leverage JavaScript as a language for styles authoring.

Why CSS-in-JS?

CSS-in-JS is has not been in the game for so long and when I'm using it I have noted som drivers that I think is behind and why developers actually likes it.

Relies on JavaScript’s modules implementation.

CSS has no concept of modules. In the component era and more and more complex applications: CSS-in-JS uses JavaScript's modules to hide the implementation details and exposing only public APIs.

Automates the scoping by generating unique selectors

We know CSS always had a single global namespace, for example, a class can be added to any element, a tag selector can target any element in the document. The entire page was styled as one big chunk. Since then the complexity of many sites has dramatically increased and this is the main reason why many CSS methodologies were created. The CSS methodologies are mostly based on convention and, it is not easy to establish and consistently enforce when many people contribute to a project over time and, it used to lead to unpredictable styles leaking.

CSS-in-JS as well as CSS Modules generate unique selectors and, our styles will be localized at the element in the DOM

<p class=”_255BVABjBx_0DfMd8sZNVs”>Localized</p>

Encourages the coupling of CSS and HTML

The idea to separate the concerns based on a language ignores the fact that CSS was not designed to be truly separated from HTML. CSS has implicit assumptions about the HTML structure. For example, flexbox layout makes an assumption that containers to position are direct children of the element it was applied to.

When a CSS rule is applied to different HTML elements across our application, we can basically describe it as a “one-to-many relationship”. If you change the CSS rule, you potentially need to modify all related HTML elements.

CSS-in-JS encourages this relationship to be "one-to-one", while still keeping the ability to have shared properties.

Gives developers API to describe state-based styles in a better way

One of the very powerful patterns CSS-in-JS enables is state-based styling. It is usually implemented as a JavaScript function which receives a state object and returns CSS properties. As a result, a CSS rule is generated that corresponds to the state of an element. Compared to a more traditional way, where we build a class attribute containing multiple class names, this has some advantages:

  1. Logic responsible for the final CSS rule has access to the state and can be located together with the rest of styles.
  2. Logic generating HTML becomes less cluttered by the classes concatenation logic.

Well, that's all for now, and I wish everybody a happy weekend. :-)

Published: 2019-11-22
Author: Henrik Grönvall
Henrik Grönvall
Copyright © 2022 Henrik Grönvall Consulting AB