Software systems to innovate and grow

Comparing CSS in JS Solutions for React Apps

By Engineering Team May 7, 2019 10 mins read

Ever since Christopher Chedeau’s infamous talk on why FaceBook switched to CSS in JS for their React projects, CSS in JS has been getting quite a lot of traction. With that, numerous CSS in JS libraries have cropped up by offering various ways of styling React applications with JavaScript. The libraries achieve this by using some additional features that make them suitable for modern component-based applications such as theming, dynamic styles, support for server-side rendering, etc.

When selecting a library for your project, you may find yourself getting a bit overwhelmed by the extensive options that are available. This article aims to help you with your decision making. We look at the top 8 CSS in JS libraries, and compare which features they offer, how to use them, as well as any strengths and/or shortcomings they may have when compared to other libraries. The 8 libraries were selected based on their download count. We selected libraries that had at least 100,000 weekly downloads at the time of writing. From the image below, you can see how the 8 have fared in the past 6 months. Of course, download count isn’t a concrete indicator of a library’s quality, but it is a good enough one as it at least offers some social proof of the libraries usefulness.

Using Local Change Detection to Optimize Performance in Angular

For each of the libraries covered, we will start with a code snippet to showcase the library’s syntax. The code will render the following two buttons.

Using Local Change Detection to Optimize Performance in Angular

The libraries are listed from the most popular to the least popular at the time of writing.

Styled-Components

With styled-components, when defining styles for your app, you create React components that have styles attached to them. The library uses ES6 Tagged Template Literals when defining components which allows you to write actual CSS for styling instead of the more common Object Literals used by other libraries. This is great for those new to CSS in JS as they can stick to writing vanilla CSS instead of getting used to the syntax of writing CSS as objects. It is also great for those migrating from a traditional external CSS code base since they will be able to reuse most of the CSS with little modification. The library also supports Style Objects for those who prefer writing CSS as JavaScript objects.

styled-components saves you from having to name your CSS classes as it generates unique class names for the styles when the page is rendered. You also don’t have to add vendor prefixes to your styles as the library does this automatically. It keeps track of components rendered on a page and only injects their styles, thus limiting loaded code to only what’s necessary.

The library supports Theming, used to provide a base styling for all your components. It also supports dynamic styles that enable a component to adapt its style based on its props or a global theme. For those who need to render their pages on the server, you will be happy to know that styled-components supports concurrent server-side rendering, with stylesheet rehydration. The library can also be used for React Native development.

Emotion

Inspired by glam, glamor, glamorous and styled-components, Emotion combines the best features these libraries have to offer to give a flexible and performant CSS in JS solution. Even though it is the newest library among our list of 8, it has quickly grown to be one of the most used CSS in JS libraries.

Emotion offers two main packages that are suitable for different projects. The emotion package is framework agnostic and is suitable for non-React JavaScript projects. For React projects, the @emotion/core package is recommended. @emotion/core has some configurations set up that the core package doesn’t—for example, it has CSS prop support and server-side rendering and theming work out of the box.

Just as with styled-components, Emotion supports both Tagged Template Literals and Object Literals. Some other features that it shares with styled-components are server-side rendering, theming, dynamic styles based on props and automatic vendor prefixing. You also don’t have to provide class names for your elements. Unique class names will be generated for you in the rendered HTML file.

To style a component, you can either add inline CSS to a component’s JSX:

Or you can create a Styled Component, i.e. a component that has styles attached to it:

Note, even though you write inline CSS when creating the component (in the first example), the rendered markup will not have inline styles, the CSS will be separated from the generated HTML.

Another great feature that comes with Emotion is that it makes UI testing easier with the jest-emotion package. With this, you can write snapshot tests with the Jest testing framework, making your app’s UI more resilient to bugs or unintended changes.

ReactCSS

ReactCSS offers you a way to style your components via inline styles. Unlike the previous two libraries we’ve looked at so far that generate a CSS that’s separate from the rendered markup, ReactCSS generates inline styles for your markup. This offers some advantages such as having scoped styles without selectors, dead code elimination and it makes it avoids specificity conflicts.

Now, as you may know, inline CSS has some limitations when it comes to some features that traditional CSS has, namely it doesn’t support pseudo-elements, pseudo-classes (:link, :visited, :hover, :active) and media queries. ReactCSS has a workaround for some of these limitations. It provides implementations for the :hover pseudo-class, pseudo-elements and media queries.

Just as with the previous two libraries, ReactCSS automatically adds vendor prefixes to your styles and supports React Native development.

When writing your styles for the component, you have to provide class names, but since the library outputs inline styles, these won’t be seen on the rendered page.

One last thing that we should mention before moving to the next library—ReactCSS hasn’t been updated since 2017, you might want to consider this when selecting a CSS in JS library for your project.

Glamor

Glamor is a framework agnostic library with great support for React. To create a component, you write inline CSS, but the final rendered page will not have inline styles. When styling your component, you provide class names, but these won’t be used as-is on the final rendered page. For Glamor and other CSS in JS libraries where you provide class names, the rendered HTML element will have a class name that is a completely new and unique string or (more common) it will have a class name that is a combination of the class name you used and a unique string. In this way, your components will always have unique class names, even if you happen to use the same class name for more than one component. In this way, your components are able to have scoped styles and avoid styling conflicts with other parts of the page, which was a big issue with traditional CSS.

The library has most of the usual features of a CSS in JS library like automatic vendor prefixing, support for server side rendering, media queries and all pseudo elements and classes.

Just as with ReactCSS, it has been a while since the library was last updated (2017), so you might want to consider this when making your decision of a library to use.

Radium

Radium is another CSS in JS library that renders inline styles. To style a component, you write the styles in an object and then pass that object to the component’s style attribute.

Just as with ReactCSS, it offers workarounds that try to overcome the limitations of inline styling. It uses JavaScript to emulate such features as :hover, :active and media queries. However, it doesn’t implement all pseudo-selectors. It only implements :hover, :active and :focus. For any other pseudo-selectors that you want to use, you’ll have to implement them yourself. There are examples in the documentation that show you how to implement :checked, :first and :last.

Other features that the library supports are automatic vendor prefixing, props-based rendering and support for server-side rendering.

Styled-JSX

With Styled-JSX, you style your components by adding styles inside <style jsx /> tags. The styles are written as template strings, so you can write pure CSS, just like with styled-components and emotion.

The library supports server-side rendering, dynamic styles and automatic vendor prefixing.

There are three ways to achieve dynamic styles:

Via interpolated dynamic props

Values that come from a component’s render method scope are treated as dynamic. Therefore, you can use props and state for dynamic styling

Via className toggling

The second option is to pass properties that can be used to toggle class names.

When using the component, you would then pass in the prop, e.g. <Button>This Button</Button>or <Button large>This Button</Button>.

Via inline style

You can override the CSS you configure via inline CSS:

In the above code, the padding will default to the one set in <style> (i.e. 20px). To change the padding dynamically, you add an inline style to the component, e.g. <Button padding={50}>.

React-JSS

React-JSS is an abstraction of the agnostic JSS library, that is more suitable for React applications.

It offers the following benefits, which are not available in the underlying core package:

  • Support for Theming
  • Extraction of Critical CSS
  • Lazy evaluation – the stylesheet is created only when the component will mount
  • Auto-attach/detach – stylesheet is rendered to the DOM when the component is about to mount and removed when no element needs it
  • A stylesheet is shared between all elements
  • Function values and rules are updated automatically with props.

The library supports server-side rendering and it performs automatic vendor prefixing.

For dynamic styling, you can use function values to define your styles. We use this in the example above to change the button’s background and color according to passed in props.

Aphrodite

Aphrodite is a framework-agnostic CSS in JS library that works great with React. To style your components, you write your styles inline, but the rendered page will not have inline styles.

The library supports server side rendering, automatic vendor prefixing, and injects only the exact styles needed for the render into the DOM.

Wrapping Up, and Choosing Your Library

Clearly, there is no shortage of CSS in JS libraries. Judging from the features of each library, it can sometimes be hard to pick a clear winner. As mentioned before, the list is arranged with regards to the number of downloads within each library. This, however, does not necessarily prove that a library is suitable for your project. When it comes to selecting a library to use, there are are other things to consider like the type of project (some projects might not even require a CSS in JS solution), the team’s willingness to use the library (some might be put off by writing CSS as objects and so they might prefer a library that uses template strings), the features that the library provides and its performance.

Whether you are in the process of deciding on a library or are just curious about the different choices out there, we hope this article gave you some insight into the 8 we covered.

Here is a brief summary of what the libraries provide:

Using Local Change Detection to Optimize Performance in Angular