CSS-in-JS in Angular or still CSS?

Hello! My name is Vsevolod Zolotov, I am a Senior Frontend at Bimeister.

CSS-in-JS has gained popularity in the React community very quickly, but how relevant is this approach in Angular? In this article, we will compare the development convenience and performance of two visually identical applications (time-tracker) written using SASS and @emotion/css.

A little background

During the existence of web development, perhaps the most popular approach to styling has become the use of the SASS preprocessor (there are others, but SASS is the most popular, we will consider it). SASS is a very powerful and proven tool that allows you to increase the abstraction level of CSS code. For example, in Angular Material, most of the styling and theming is done using SASS. Using the large set of constructs offered by SASS, one involuntarily asks the question: “Are there alternative options for styling applications?”.

Of course have! One of the popular alternatives currently is CSS-in-JS (according to the State of CSS). Most developers use less than 30% of preprocessor capabilities and hardly ever heard of maps, lists and other constructs. Why not let developers use the power of CSS inside JavaScript?

CSS-in-JS has gained popularity in the React community very quickly. This is because React developers have been repeating the same mantra for years – “Everything will be JavaScript”. Therefore, most CSS-in-JS solutions were originally developed for React. But there are also framework-agnostic libraries, one of which was used for comparison with SASS, – @emotion/css.

Crossing CSS-in-JS with Angular

Disclaimer: There are a huge number of articles comparing CSS-in-JS and CSS, so don’t expect this article to list all possible problems and the theoretical part. In this paper, we compared the two approaches in practice.

CSS-in-JS or CSS-in-CSS?

“Write CSS-in-CSS,” they said, and of course they were right. So everyone did, until the component approach appeared.

The key problem with CSS in the component world is that it was originally designed for the page world. CSS has only one global namespace and no access to component states.

It should be noted that component-based frameworks have solved these, and more, CSS problems in different ways. Styling has become less of a pain. In Angular, styles are isolated at the component level, Vue has scoped styles, and React has CSS modules. But CSS never got easy access to component state.

How Frameworks Solve CSS Problems
How Frameworks Solve CSS Problems

Does CSS need access to the state of components?

Perhaps not needed. This article does not aim to sell the CSS-in-JS approach, because you can get by with modifier classes, and dynamically change styles if necessary. We will use inline styles. But CSS-in-JS allows you to unify your approach to styling and forget about inline styles, modifiers, etc.

How does @emotion/css work?

To understand how @emotion/css actually works, it took a look at the source code.

The library accepts SASS / SCSS-like code, but only selectors – no mixins and similar constructs. It makes no sense to describe the principle of @emotion / css in words, so I suggest taking a look at a simplified flowchart.

Simplified flowchart of how @emotion/css works
Simplified flowchart of how @emotion/css works

It should be noted that if the input to the function css() previously processed code gets into it, then thanks to caching in the tag <head> new tags <style> will not be added, and the function will return the already known CSS class. Therefore, when working with @emotion/css, we advise you to separate static and dynamic styles into separate classes – this way you will increase application performance and save on debugging.

tags generated by @emotion/css look like” title=”How CSS classes and