DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!
In this article, we’re going to dig into the concept of CSS-in-JS. If you’re already acquainted with this concept, you might still enjoy a stroll through the philosophy of that approach, and you might be even more interested in the next article.
Web development is very interdisciplinary. We’re used to working closely with multiple languages. And, as developing web applications becomes more commonplace and nuanced, we often look for creative ways to bridge the gaps between those languages to make our development environments and workflows easier and more efficient.
The most common examples are typically when using templating languages. For example, one language might be used to generate the code of a more verbose language (often HTML). This is one of the key aspects of front end frameworks — what does manipulating HTML look like? The most recent twist in this area was JSX because it’s not really a templating language; it’s a syntax extension to JavaScript, and it makes working with HTML really succinct.
Web applications go through many state combinations and it’s often challenging to manage content alone. This is why CSS sometimes falls by the wayside — even though managing styling through different states and media queries is equally important and just as challenging. In this two-part series, I would like to place CSS in the spotlight and explore bridging the gap between it and JavaScript. Throughout this series, I will assume that you’re using a module bundler like webpack. As such, I will use React in my examples, but the same or similar principles are applicable to other JavaScript frameworks, including Vue.
The CSS landscape is evolving in many directions because there are a lot of challenges to solve and there is no “correct” path. I’ve been spending considerable effort experimenting with various approaches, mostly on personal projects, so the intention behind this series is only to inform, not to prescribe.
Challenges of CSS
Before diving into code, it’s worth explaining the most notable challenges of styling web applications. The ones I’ll talk about in this series are scoping, conditional and dynamic styles, and reusability.
Scoping
Scoping is a well-known CSS challenge, it’s the idea of writing styles that don’t leak outside of the component, thus avoid unintended side effects. We would like to achieve it ideally without compromising authoring experience.
Conditional and dynamic styles
While the state in front-end applications started getting more and more advanced, CSS was still static. We were only able to apply sets of styles conditionally — if a button was primary, we would probably apply the class “primary” and define its styles in a separate CSS file to apply how it’s going to look like on the screen. Having a couple of predefined button variations was manageable, but what if we want to have a variety of buttons, like specific ones tailored for Twitter, Facebook, Pinterest and who knows what else? What we really want to do is simply pass a color and define states with CSS like hover, focus, disabled etc. This is called dynamic styling because we’re no longer switching between predefined styles — we don’t know what’s coming next. Inline styles might come to mind for tackling this problem, but they don’t support pseudo-classes, attribute selectors, media queries, or the like.
Reusability
Reusing rulesets, media queries etc. is a topic I rarely see mentioned lately because it’s been solved by preprocessors like Sass and Less. But I’d still like to revisit it in this series.
I will list some techniques for dealing with these challenges along with their limitations in both parts of this series. No technique is superior to the others and they aren’t even mutually exclusive; you can choose one or combine them, depending on what you decide will improve the quality of your project.
Setup
We’ll demonstrate different styling techniques using an example component called Photo. We’ll render a responsive image that may have rounded corners while displaying alternative text as a caption. It will be used like this:
<Photo publicId="balloons" alt="Hot air balloons!" rounded />
Before building the actual component, we’ll abstract away the srcSet attribute to keep the example code brief. So, let’s create a utils.js file with two utilities for generating images of different widths using Cloudinary:
We set up our Cloudinary instance to use the name of Cloudinary’s demo cloud, as well as its url method to generate URLs for the image publicId according to the specified options. We’re only interested in modifying the width in this component.
We’ll use these utilities for the src and srcset attributes, respectively:
If you’re unfamiliar with srcset and sizes attributes, I suggest reading a bit about responsive images first. That way, you’ll have an easier time following the examples.
CSS-in-JS
CSS-in-JS is a styling approach that abstracts the CSS model to the component level, rather than the document level. This idea is that CSS can be scoped to a specific component — and only that component — to the extent that those specific styles aren’t shared with or leaked to other components, and further, called only when they’re needed. CSS-in-JS libraries create styles at runtime by inserting <style> tags in the <head>.
One of the first libraries to put this concept to use is JSS. Here is and example employing its syntax:
At first glance, the styles object looks like CSS written in object notation with additional features, like passing a function to set the value based on props. The generated classes are unique, so you never need to worry about them clashing with other styles. In other words, you get scoping for free! This is how most CSS-in-JS libraries work — of course, with some twists in features and syntax that we’ll cover as we go.
You can see by the attributes that the width of our rendered image starts at 200px, then when the viewport width becomes at least 30rem, the width increases to 400px wide. We generated an extra 800 source to cover even larger screen densities:
1x screens will use 200 and 400
2x screens will use 400 and 800
styled-components is another CSS-in-JS library, but with a much more familiar syntax that cleverly uses tagged template literals instead of objects to look more like CSS:
We often create semantically-neutral elements like <div> and <span> solely for styling purposes. This library, and many others, allow us to create and style them in a single motion.
My favorite benefit of this syntax is that it’s like regular CSS, minus interpolations. This means that we can migrate our CSS code more easily and we get to use our existing muscle memory instead of having to familiarize ourselves with writing CSS in the object syntax.
Notice that we can interpolate almost anything into our styles. This specific example demonstrates how we can save the media query in the variable and reuse it in multiple places. Responsive images are an excellent use case for this because the sizes attribute contains basically CSS, so we can use JavaScript to make the code more DRY.
Let’s say that we decided we want to visually hide the caption, but still make it accessible for screen readers. I know that a better way of achieving this would be to use an alt attribute instead, but let’s use a different way for the sake of this example. We can use a library of style mixins called polished — it works great with CSS-in-JS libraries making it great for our example. This library includes a mixin called hideVisually which does exactly what we want and we can use it by interpolating its return value:
Even though hideVisually outputs an object, the styled-components library knows how to interpolate it as styles.
CSS-in-JS libraries have many advanced features like theming, vendor prefixing and even inlining critical CSS, which makes it easy to stop writing CSS files entirely. At this point, you can start to see why CSS-in-JS becomes an enticing concept.
Downsides and limitations
The obvious downside to CSS-in-JS is that it introduces a runtime: the styles need to be loaded, parsed and executed via JavaScript. Authors of CSS-in-JS libraries are adding all kinds of smart optimizations, like Babel plugins, but some runtime costs will nevertheless exist.
It’s also important to note that these libraries aren’t being parsed by PostCSS because PostCSS wasn’t designed to be brought into the runtime. Many use stylis instead as a result because it’s much faster. This means that we unfortunately can’t use PostCSS plugins.
The last downside I’ll mention is the tooling. CSS-in-JS is evolving at a really fast rate and text editor extension, linters, code-formatters etc. need to play catch-up with new features to stay on par. For example, people are using the VS Code extension styled-components for similar CSS-in-JS libraries like emotion, even though they don’t all have the same features. I’ve even seen API choices of proposed features being influenced by the goal of retaining syntax highlighting!
The future
There are two new CSS-in-JS libraries, Linaria and astroturf, that have managed zero runtime by extracting CSS into files. Their APIs are similar to styled-components, but they vary in features and goals.
The goal of Linaria is to mimic the API of CSS-in-JS libraries like styled-components by having built-in features like scoping, nesting and vendor prefixing. Conversely, astroturf is built upon CSS Modules, has limited interpolation capabilities, and encourages using a CSS ecosystem instead of deferring to JavaScript.
I built Gatsby plugins for both libraries if you want to play with them:
Two things to have in mind when using these libraries:
having actual CSS files means that we can process them with familiar tools like PostCSS
Linaria uses custom properties (a.k.a. CSS variables) under the hood, be sure to take their browser support into consideration before using this library
Conclusion
CSS-in-JS are all-in-one styling solutions for bridging the gap between CSS and JavaScript. They are easy to use and they contain useful built-in optimizations — but all of that comes at a cost. Most notably, by using CSS-in-JS, we’re essentially ejecting from the CSS ecosystem and deferring to JavaScript to solve our problems.
Zero-runtime solutions mitigate some of the downsides by bringing back the CSS tools, which ascends the CSS-in-JS discussion to a much more interesting level. What are the actual limitations of preprocessing tools compared to CSS-in-JS? This will be covered in the next part of this series.
At first glance, the styles object looks like CSS written in object notation with additional features, like passing a function to set the value based on props. The generated classes are unique, so you never need to worry about them clashing with other styles. In other words, you get scoping for free! This is how most CSS-in-JS libraries work — of course, with some twists in features and syntax that we’ll cover as we go.
You can see by the attributes that the width of our rendered image starts at 200px, then when the viewport width becomes at least 30rem, the width increases to 400px wide. We generated an extra 800 source to cover even larger screen densities:
1x screens will use 200 and 400
2x screens will use 400 and 800
styled-components is another CSS-in-JS library, but with a much more familiar syntax that cleverly uses tagged template literals instead of objects to look more like CSS:
We often create semantically-neutral elements like
and solely for styling purposes. This library, and many others, allow us to create and style them in a single motion.
My favorite benefit of this syntax is that it’s like regular CSS, minus interpolations. This means that we can migrate our CSS code more easily and we get to use our existing muscle memory instead of having to familiarize ourselves with writing CSS in the object syntax.
Notice that we can interpolate almost anything into our styles. This specific example demonstrates how we can save the media query in the variable and reuse it in multiple places. Responsive images are an excellent use case for this because the sizes attribute contains basically CSS, so we can use JavaScript to make the code more DRY.
Let’s say that we decided we want to visually hide the caption, but still make it accessible for screen readers. I know that a better way of achieving this would be to use an alt attribute instead, but let’s use a different way for the sake of this example. We can use a library of style mixins called polished — it works great with CSS-in-JS libraries making it great for our example. This library includes a mixin called hideVisually which does exactly what we want and we can use it by interpolating its return value:
Even though hideVisually outputs an object, the styled-components library knows how to interpolate it as styles.
CSS-in-JS libraries have many advanced features like theming, vendor prefixing and even inlining critical CSS, which makes it easy to stop writing CSS files entirely. At this point, you can start to see why CSS-in-JS becomes an enticing concept.
Downsides and limitations
The obvious downside to CSS-in-JS is that it introduces a runtime: the styles need to be loaded, parsed and executed via JavaScript. Authors of CSS-in-JS libraries are adding all kinds of smart optimizations, like Babel plugins, but some runtime costs will nevertheless exist.
It’s also important to note that these libraries aren’t being parsed by PostCSS because PostCSS wasn’t designed to be brought into the runtime. Many use stylis instead as a result because it’s much faster. This means that we unfortunately can’t use PostCSS plugins.
The last downside I’ll mention is the tooling. CSS-in-JS is evolving at a really fast rate and text editor extension, linters, code-formatters etc. need to play catch-up with new features to stay on par. For example, people are using the VS Code extension styled-components for similar CSS-in-JS libraries like emotion, even though they don’t all have the same features. I’ve even seen API choices of proposed features being influenced by the goal of retaining syntax highlighting!
The future
There are two new CSS-in-JS libraries, Linaria and astroturf, that have managed zero runtime by extracting CSS into files. Their APIs are similar to styled-components, but they vary in features and goals.
The goal of Linaria is to mimic the API of CSS-in-JS libraries like styled-components by having built-in features like scoping, nesting and vendor prefixing. Conversely, astroturf is built upon CSS Modules, has limited interpolation capabilities, and encourages using a CSS ecosystem instead of deferring to JavaScript.
I built Gatsby plugins for both libraries if you want to play with them:
Two things to have in mind when using these libraries:
having actual CSS files means that we can process them with familiar tools like PostCSS
Linaria uses custom properties (a.k.a. CSS variables) under the hood, be sure to take their browser support into consideration before using this library
Conclusion
CSS-in-JS are all-in-one styling solutions for bridging the gap between CSS and JavaScript. They are easy to use and they contain useful built-in optimizations — but all of that comes at a cost. Most notably, by using CSS-in-JS, we’re essentially ejecting from the CSS ecosystem and deferring to JavaScript to solve our problems.
Zero-runtime solutions mitigate some of the downsides by bringing back the CSS tools, which ascends the CSS-in-JS discussion to a much more interesting level. What are the actual limitations of preprocessing tools compared to CSS-in-JS? This will be covered in the next part of this series.
If you use a meta tag as follows: http-equiv=”Content-Security-Policy” content=”default-src ‘self'” to try and stop XSS attacks, won’t that prevent the injected inline styles from working if you are using this system? Conversley, aren’t you creating a vulnerability by injecting inline styles?
Thanks for the reply Matija. As an example, this meta tag: is used on this site: http://www.nown.org.au/ in an effort to avoid XSS attacks – the injection of malicious code. The details/reasoning can be found on this link: https://developers.google.com/web/fundamentals/security/csp/
Using the Content Security Policy in this way prevents a browser from using any code that does not emanate from the server on which the HTML is stored, as I understand it.
As a consequence, however, the browser will not recognize or run any inline js code (eg: onclick=”myFunction()”) nor any inline CSS (e.g. style =”color:black;”). And style tags in the head section are also rendered ineffective; will not work at all.
All your JS and CSS (and JQuery) has to come from separate files stored on the same server as the page; i.e. ‘self’.
So that was my question: is the injection of, for example, style tags by CSS-inJS compatible with the use of a strict Content Security Policy such as ‘self.’
If it is, does this create a vulnerability?
Or have I got this all wrong anyway?
Sorry for answering so late, I kept this one in my inbox all this time because I wanted to check it out. Indeed it prevents injecting styles, I just tried it! It seems like you can get around it with nonce, though. I don’t know how much of a problem this is because security isn’t my strong suit. But styled-components has info about this.
I am deeply against CSS-in-JS mainly for separation of concerns.
The problems CSS-in-JS tries to solve is largely due to a lack of knowledge and experience of CSS by developers. A style doesn’t “leak”. The C in CSS stands for “Cascading”, it means that the entire spirit of CSS is to “leak” downwards. It is a feature, not a weakness, you just have to learn how to use it. There are techniques, methods for this, and they perfectly scale.
A symbol of this? Your import of “hideVisually”. You’re importing a JS object meant to insert a pre-made class inside your component, and isolate it from the rest of the page. Don’t you think this would be the precise use of CSS? Having this class, as a standard CSS class, available for the whole page, called on the components that needs it? It would be shared, no processing time, just plain old CSS.
Precise benefits of CSS-in-JS are better illustrated elsewhere on the web, they wouldn’t fit into one article. This is more of an overview and a setup for the 2nd part.
Both parts of this series are closely related, you might like the 2nd one better. ;)
So if the evolution of CSS in JS is extracting it at compile time (and I agree), why not just use SASS? Combined with CSS Modules at the component level, you get everything you get from CSS in JS but without the tons of extra boilerplate/syntax, performance overhead and a zillion implementations. You also have a first class cascading system available when you need it because well… you’re designing a theme that is supposed to provide a unique branding for something.
I’m sure this sounds grumpy (and yeah I’ve seen the memes by smart ass hipsters), but out of all the front end changes, most excite me, but this I feel frustrated by to the point that I sometimes question how long I’ll want to continue front end development. I absolutely hate coming into a project with CSS in JS. It turns components into a spaghetti that is so much harder to reason about without the separation of concerns or the ability to quickly iterate and reuse 20 years worth of community CSS. Not to mention all the various architectures of it. It slows me way down and it isn’t fun. And I’m a full stack developer who loves good code.
The main problem is that CSS modules came late to the party a lot of folks didn’t notice. CSS modules proved that the argument about encapsulation is a dishonest one and one that has no business being used as an argument anymore. SASS, LESS, have what you need in terms of flexibility. A lot of what they do are unnecessary at runtime. With CSS in JS you’re both shipping a lot of extra bytes and doing more processing that you would with simple metadata for style.
I empathize with your frustrations. As a styling enthusiast I was desperately searching for best practices and, as much as I enjoyed the flexibility of CSS-in-JS, I couldn’t keep up with it. This brought me to the 2nd part of this series, I suggest you give it a look. ;)
Serious question: what is the use case for CSS-in-JS over simply swapping out a class or two, or using a build tool to achieve the same thing? Maybe the apps I work on aren’t large enough to see a benefit, but I’m just not convinced this is a good idea.
I am a bit old school developer. I remember days when we got hard fights to separate HTML, CSS and JS and it was great victory in web development when people started to store HTML, JS and CSS separately. Novadays new generation of webdevs came to scene and everything is back, where we started about 15 years ago. Sorry, but for me CSS-in-JS idea is unacceptable. I have already seen where this might lead to.
CSS-in-JS could sure be helpful for a lot of people. And some implementations could be working just fine… IF and only IF they are implemented in a smart way.
However, the way of implementing CSS-in-JS, especially as it is described here above where you can inject values from “props” (as JS-variables), could be a direct attack on the performance of the render-cycle of our beloved browsers!
That is because, unfortunately, not all developers know the inner workings of the browser. Most of them won’t even remember the downsides mentioned in this article after reading it. So up until some standardisation (like the W3C) comes up with a proper solution, please do not advocate the use of CSS-in-JS.
This article has the potential of making “the internet” worse instead of making it better.
Think of the user happiness, not the developer happiness!
There are lots of things to consider. For example, inlining critical CSS also makes users happy, but it’s hard to do, so many developers don’t do it. CSS-in-JS gives it to you for free. :)
Note that authors of CSS-in-JS libraries have been optimizing them up to the point of removing the runtime entirely! It’s important to inspect what CSS-in-JS actually compiles down to.
Matija Marohnić, you can’t get rid of the runtime entirely, that would bring the whole thing back down to plain old CSS. There is a performance hit with CSS-in-JS, that will always exist.
Ashley, most CSS-in-JS libraries do have a runtime, yes, but astroturf and Linaria don’t have one, that’s what I was referring to. See for yourself, they compile to actual CSS files. Now, whether that’s a good idea is up to you. ;)
I am really trying to see the point, but I keep thinking: if you know what you are doing with CSS, CSS ‘leaking’ is not ever a problem. The only problem I ever had with leaking is libraries that have bad CSS. I just remove those styles and rewrite it quick to fit the project.
If you really don’t like the whole cascading thing, why not use ID’s? React is made of modules, give that module an ID and style from there – voila. styles will not ever leak. I think this is bad practice, but it’s essentially the same a modularizing your CSS? Which makes modularization also a bad practice? You still want (some) global styles right?
I am still confused about the benefits of CSS-in-JS should deliver. I keep thinking I am missing the point and I would really like to understand.
The benefits go far beyond modularization, this Twitter thread might help. Personally, I’m looking for alternatives, so check out the 2nd part of this series. ;)
CSS inside of JS components are becoming more popular because the traditionalists are being edged out of the FED game, as pure JS programmers overtake them, not because it’s a better idea…which it isn’t.
CSS in Javascript is a horrible idea! One of the true strengths of Cascading Style Sheets is the Cascading, which most modern developers do not understand the power it gives. People today do not think of CSS as being a skin and HTML as the scaffolding. Separating the concerns also allows developers to work in parallel, one working on the scaffolding and the other the skin. Does anyone remember http://www.csszengarden.com? Showing the true power of CSS! (I could write a whole article on this topic, which I might ;)
Only used CSS-in-JS once using styled components, it was an awful frustrating experience, much more complicated but with less re-use than using plain old stylesheets. We were using 3 libraries to achieve a more complicated solution than just using CSS, seemed very over engineered to me and goes against the old principles of separation of concerns.
I agree with others here the reason that CSS in JS is being pushed is because a lot of dev’s don’t want to learn how to do CSS correctly, which is unfortunate because being good at CSS combined with decent HTML can create the most elegant and simple solutions using the least code. It seems that the developer experience is becoming more important than the user experience ie things are done to benefit the dev rather than the user.
Still I guess I am whistling at the wind.
This comment thread is closed. If you have important information to share, please contact us.
If you use a meta tag as follows: http-equiv=”Content-Security-Policy” content=”default-src ‘self'” to try and stop XSS attacks, won’t that prevent the injected inline styles from working if you are using this system? Conversley, aren’t you creating a vulnerability by injecting inline styles?
Interesting, please tell me more! Example? Also, CSS-in-JS doesn’t inject inline styles, did you mean
style
tags?Thanks for the reply Matija. As an example, this meta tag: is used on this site: http://www.nown.org.au/ in an effort to avoid XSS attacks – the injection of malicious code. The details/reasoning can be found on this link: https://developers.google.com/web/fundamentals/security/csp/
Using the Content Security Policy in this way prevents a browser from using any code that does not emanate from the server on which the HTML is stored, as I understand it.
As a consequence, however, the browser will not recognize or run any inline js code (eg: onclick=”myFunction()”) nor any inline CSS (e.g. style =”color:black;”). And style tags in the head section are also rendered ineffective; will not work at all.
All your JS and CSS (and JQuery) has to come from separate files stored on the same server as the page; i.e. ‘self’.
So that was my question: is the injection of, for example, style tags by CSS-inJS compatible with the use of a strict Content Security Policy such as ‘self.’
If it is, does this create a vulnerability?
Or have I got this all wrong anyway?
Sorry for answering so late, I kept this one in my inbox all this time because I wanted to check it out. Indeed it prevents injecting styles, I just tried it! It seems like you can get around it with nonce, though. I don’t know how much of a problem this is because security isn’t my strong suit. But styled-components has info about this.
I am deeply against CSS-in-JS mainly for separation of concerns.
The problems CSS-in-JS tries to solve is largely due to a lack of knowledge and experience of CSS by developers. A style doesn’t “leak”. The C in CSS stands for “Cascading”, it means that the entire spirit of CSS is to “leak” downwards. It is a feature, not a weakness, you just have to learn how to use it. There are techniques, methods for this, and they perfectly scale.
A symbol of this? Your import of “hideVisually”. You’re importing a JS object meant to insert a pre-made class inside your component, and isolate it from the rest of the page. Don’t you think this would be the precise use of CSS? Having this class, as a standard CSS class, available for the whole page, called on the components that needs it? It would be shared, no processing time, just plain old CSS.
Precise benefits of CSS-in-JS are better illustrated elsewhere on the web, they wouldn’t fit into one article. This is more of an overview and a setup for the 2nd part.
Both parts of this series are closely related, you might like the 2nd one better. ;)
So if the evolution of CSS in JS is extracting it at compile time (and I agree), why not just use SASS? Combined with CSS Modules at the component level, you get everything you get from CSS in JS but without the tons of extra boilerplate/syntax, performance overhead and a zillion implementations. You also have a first class cascading system available when you need it because well… you’re designing a theme that is supposed to provide a unique branding for something.
I’m sure this sounds grumpy (and yeah I’ve seen the memes by smart ass hipsters), but out of all the front end changes, most excite me, but this I feel frustrated by to the point that I sometimes question how long I’ll want to continue front end development. I absolutely hate coming into a project with CSS in JS. It turns components into a spaghetti that is so much harder to reason about without the separation of concerns or the ability to quickly iterate and reuse 20 years worth of community CSS. Not to mention all the various architectures of it. It slows me way down and it isn’t fun. And I’m a full stack developer who loves good code.
The main problem is that CSS modules came late to the party a lot of folks didn’t notice. CSS modules proved that the argument about encapsulation is a dishonest one and one that has no business being used as an argument anymore. SASS, LESS, have what you need in terms of flexibility. A lot of what they do are unnecessary at runtime. With CSS in JS you’re both shipping a lot of extra bytes and doing more processing that you would with simple metadata for style.
I empathize with your frustrations. As a styling enthusiast I was desperately searching for best practices and, as much as I enjoyed the flexibility of CSS-in-JS, I couldn’t keep up with it. This brought me to the 2nd part of this series, I suggest you give it a look. ;)
Serious question: what is the use case for CSS-in-JS over simply swapping out a class or two, or using a build tool to achieve the same thing? Maybe the apps I work on aren’t large enough to see a benefit, but I’m just not convinced this is a good idea.
This Twitter thread might be helpful.
I am a bit old school developer. I remember days when we got hard fights to separate HTML, CSS and JS and it was great victory in web development when people started to store HTML, JS and CSS separately. Novadays new generation of webdevs came to scene and everything is back, where we started about 15 years ago. Sorry, but for me CSS-in-JS idea is unacceptable. I have already seen where this might lead to.
CSS-in-JS is just one approach, the 2nd part of this series features a modern approach to old-school CSS. ;)
CSS-in-JS could sure be helpful for a lot of people. And some implementations could be working just fine… IF and only IF they are implemented in a smart way.
However, the way of implementing CSS-in-JS, especially as it is described here above where you can inject values from “props” (as JS-variables), could be a direct attack on the performance of the render-cycle of our beloved browsers!
That is because, unfortunately, not all developers know the inner workings of the browser. Most of them won’t even remember the downsides mentioned in this article after reading it. So up until some standardisation (like the W3C) comes up with a proper solution, please do not advocate the use of CSS-in-JS.
This article has the potential of making “the internet” worse instead of making it better.
Think of the user happiness, not the developer happiness!
There are lots of things to consider. For example, inlining critical CSS also makes users happy, but it’s hard to do, so many developers don’t do it. CSS-in-JS gives it to you for free. :)
Note that authors of CSS-in-JS libraries have been optimizing them up to the point of removing the runtime entirely! It’s important to inspect what CSS-in-JS actually compiles down to.
Matija Marohnić, you can’t get rid of the runtime entirely, that would bring the whole thing back down to plain old CSS. There is a performance hit with CSS-in-JS, that will always exist.
Ashley, most CSS-in-JS libraries do have a runtime, yes, but astroturf and Linaria don’t have one, that’s what I was referring to. See for yourself, they compile to actual CSS files. Now, whether that’s a good idea is up to you. ;)
I am really trying to see the point, but I keep thinking: if you know what you are doing with CSS, CSS ‘leaking’ is not ever a problem. The only problem I ever had with leaking is libraries that have bad CSS. I just remove those styles and rewrite it quick to fit the project.
If you really don’t like the whole cascading thing, why not use ID’s? React is made of modules, give that module an ID and style from there – voila. styles will not ever leak. I think this is bad practice, but it’s essentially the same a modularizing your CSS? Which makes modularization also a bad practice? You still want (some) global styles right?
I am still confused about the benefits of CSS-in-JS should deliver. I keep thinking I am missing the point and I would really like to understand.
The benefits go far beyond modularization, this Twitter thread might help. Personally, I’m looking for alternatives, so check out the 2nd part of this series. ;)
CSS inside of JS components are becoming more popular because the traditionalists are being edged out of the FED game, as pure JS programmers overtake them, not because it’s a better idea…which it isn’t.
It feels like a FAD and a bad idea…because it is.
CSS in Javascript is a horrible idea! One of the true strengths of Cascading Style Sheets is the Cascading, which most modern developers do not understand the power it gives. People today do not think of CSS as being a skin and HTML as the scaffolding. Separating the concerns also allows developers to work in parallel, one working on the scaffolding and the other the skin. Does anyone remember http://www.csszengarden.com? Showing the true power of CSS! (I could write a whole article on this topic, which I might ;)
Only used CSS-in-JS once using styled components, it was an awful frustrating experience, much more complicated but with less re-use than using plain old stylesheets. We were using 3 libraries to achieve a more complicated solution than just using CSS, seemed very over engineered to me and goes against the old principles of separation of concerns.
I agree with others here the reason that CSS in JS is being pushed is because a lot of dev’s don’t want to learn how to do CSS correctly, which is unfortunate because being good at CSS combined with decent HTML can create the most elegant and simple solutions using the least code. It seems that the developer experience is becoming more important than the user experience ie things are done to benefit the dev rather than the user.
Still I guess I am whistling at the wind.