Improve Your App with CSS in JavaScript

I’m bootstrapping a web project for the first time in a while, and I was surprised to find that CSS-in-JavaScript libraries are now a thing. Despite my initial surprise, I’ve come to believe it’s actually a great idea.

What is CSS-in-JS?

Unlike me, you may have already heard of these tools, with names like emotion, glamor, and JSS. It seems they have varying approaches, tradeoffs, and APIs, but here’s the gist of it:

  • You define your CSS properties as JavaScript objects that look sort of like CSS.
  • The library you’re using, at runtime in the browser, compiles this into real CSS and manages the insertion (and perhaps removal) of CSS classes for you.
  • You receive the generated names for these CSS classes, and you can use them in your UI library just like normal.

The usual benefits are touted to be things like the ability to:

  • Side-step the entire CSS specificity rule disaster
  • Define your helper functions in regular JavaScript
  • Co-locate your CSS with your React components

To be sure, these benefits are awesome in their own right. However, plenty of other resources around the web have covered them, so I’m going to focus on two others that have really won me over.

Type Checking and Inline Documentation

On our project, we are able to receive on-the-fly, as-you-type error checking and documentation. This is made possible thanks to the confluence of VS Code, TypeScript, and the csstype library.

Right away, we’re able to see:

  • Whether we correctly spelled the name of the CSS property
  • If the value is roughly correct
  • Inline documentation from MDN!
  • Browser compatibility info
  • Naturally, it’s also possible to auto-complete the names of CSS properties and their values, or to hover over existing code to see documentation. It’s extremely helpful.

    Laziness

    On our project, we are co-locating our styles with our React components and using Material-UI’s new styles package to leverage their new Hooks-based API. This is great for several reasons, but it also allows us to compute our CSS from props that are passed in to our React components. In general, our CSS isn’t even compiled (or inserted into the DOM) until it is needed to render a given component.

    We’re also using webpack, and this allows us to do some advanced things with how our JavaScript is loaded. For instance:

    • All our code is loaded incrementally as the user navigates to different pages, which improves the experience of loading and using the app.
    • When we do a production build, webpack prunes out dead code.

    These benefits are conferred to our CSS, too, because our CSS is JavaScript.

    The net effect of all this is that you don’t need to worry about your old crufty CSS accumulating in your codebase, too afraid to delete it for fear that it will cause subtle visual bugs.

    Conclusion

    I’m quite surprised to find that there aren’t any serious drawbacks to this approach. There’s some small additional amount of JavaScript required, but the benefits are numerous and lead to a much nicer development experience. I’d highly recommend using a CSS-in-JS library on your next web project.