The CSS-in-JS Styling Technique

Updated Mar 29, 2021#css#guides

No longer do you have to maintain a bunch of stylesheets, it abstracts the CSS model to the component level and leverages the whole power of JavaScript! Yes I’m talking about CSS-in-JS which is trending in frontend development.

There’s always a standard of separating styling from markup since the inception of web development. HTML presentation tags were deprecated in favor of CSS files to completely separate from HTML document. And everyone has been happy with that, CSS styling is very mature with standards and techniques.

Using external CSS stylesheets has obvious benefit when you can update the styles across a whole website by updating a single document and we’re all hooked with that.

React came in town and changed everything! CSS-in-JS was born and loved by community (me too!). It’s moving in the opposite direction of style portability. What were the reasons behind it and should you adopt it? Let’s take a look at two sides of the rising star!

Motivation

CSS at scale has some problems like dependencies, dead code elimination, minification, sharing constants, non-deterministic resolution and isolation.

CSS uses a global namespace for CSS selectors that can easily result in style conflicts throughout your application when building an application using modern web components. You can avoid this problem by nesting CSS selectors or use a styling convention like BEM but this becomes complicated quickly and won’t scale.

CSS-in-JS avoids these problems entirely by generating unique class names when styles are converted to CSS. This allows you to think about styles on a component level with out worrying about styles defined elsewhere.

CSS-in-JS is a different styling technique where CSS is composed using JavaScript instead of defined in external files. It offers a compelling set of features to supercharge your developer experience and ensure your team can move fast.

CSS-in-JS is a delicate and controversial topic, you should approach it with an open mind.

Benefits

CSS-in-JS was born to abstract away many complicated CSS concepts like cascading, specificity, naming selectors, enforcing naming conventions, enforcing file structures, preprocessors.

  • Everything is component: Your styles only affect the component they’re applied to. This means you can customize your component’s CSS without worrying about how it will impact the rest of your application. Seamlessly add and remove components without constantly ballooning stylesheet size and complexity.
  • Dynamic styling: Using variables and functions in CSS in quite limited, especially the need of dynamic styling based on contexts. CSS-in-JS makes easy to integrate with JavaScript variables, functions and themes.
  • Maintainable at scale: With the scoping of CSS-in-JS, teams can organize their styles in isolation without affecting one another. Stop worrying about mandated conventions and remove the need for application-wide selector hierarchies and naming schemes altogether.
  • Intuitive and automated: Many CSS-in-JS libraries generate unique class names which can help with caching, automatic vendor prefixes, timely loading of critical CSS, dead code elimination, and implementing many other features, depending on the library you choose.
  • React Native compatible: Some libraries support RN, I’ve been using styled-components in my RN projects and you don’t know how grateful I am.

Drawbacks

Nothing is perfect and so is CSS-in-JS. It has some drawbacks which might shy you away from adopting it in your company.

  • Lack of portability: It’s an obvious disadvantage when CSS-in-JS was designed to be written in JavaScript, which makes it hard to move around projects using different frontend languages like PHP, JavaScript, or Ruby.
  • Steep learning curve: For people who are familiar with CSS, but are new to JavaScript, the initial amount of work to get up to speed with CSS-in-JS might not be large but it does exist.
  • Unreadable class names: Most CSS-in-JS libraries generate random unreadable class names which might be a problem if you need meaningful names for other purposes like debugging or crawling.
  • Performance: Might be a problem in early days, but now libraries automatically handle critical css and compiling very well means their performance is very close to normal stylesheets.

Libraries

There are many CSS-in-JS techniques out there with different quality, you can try any of them for fun but definitely should only use popular ones for production. Following libraries are well developed and maintained by community:

  • css-modules: An approach that tries to fix global scope of CSS by let you use the same CSS class name in different files without worrying about naming clashes, made possible by webpack’s css-loader or postcss-loader.
  • styled-components: By far this library is the best and most loved solution with more than 25k stars on GitHub. I’ve been using it for 2 years and the experience is more than satisfied. Its ecosystem is getting bigger, you simply just can’t stop using it.
  • emotion: The second best solution with 9k stars. This one focuses on performance and flexibility; It allows you to style apps quickly with string or object styles.
  • polished: A lightweight tool set for writing styles in JavaScript. No matter if you’re using styled-components, emotion, jss, aphrodite, radium, or plain inline styles, as long as you’re writing your styles in JavaScript you can use polished.
  • jss: An authoring tool for CSS which allows you to use JavaScript to describe styles in a declarative, conflict-free and reusable way. It can compile in the browser, server-side or at build time in Node. JSS is framework agnostic, you can use along with other frameworks using adapters like styled-jss or glamor-jss.
  • radium: A set of tools to manage inline styles on React elements. It gives you powerful styling capabilities without CSS.
  • aphrodite: A framework-agnostic CSS-in-JS library with support for server-side rendering, browser prefixing, and minimum CSS generation.
  • glamor: A small, fast, efficient, framework independent CSS-in-JS library. It lets you write inline CSS in your components using the same Object CSS syntax React supports for the style prop.

Check out all css-in-js libraries here.

Conclusions

CSS-in-JS is just a better way of writing CSS, its mission is to make your life as JavaScript Frontend Developer easier, not to be confused with replacing CSS completely. So CSS-in-JS does not get rid of the need to understand how CSS works.

The CSS-in-JS technique is till very young compared to 10+ years history of CSS, but it is evolving very fast in recent years. You should give it a try on side projects using JS frameworks, especially styled-components, I bet you’ll love it the moment you touch it.

If you think the pros outweighs the cons, then give CSS-in-JS a shot!

I have strong belief that sooner or later we’re going to develop websites like we’re developing mobile apps; When we only use JavaScript to build a complete website without writing any raw HTML/CSS lines of code.