Some people outright hate the idea of CSS-in-JS. Just that name is offensive. Hard no. Styling doesn’t belong in JavaScript, it belongs in CSS, a thing that already exists and that browsers are optimized to use. Separation of concerns. Anything else is a laughable misstep, a sign of not learning from the mistakes of the past (like the <font>
tag and such.)
Some people outright love the idea of CSS-in-JS. The co-location of templates and functionality, à la most JavaScript frameworks, has proven successful to them, so wrapping in styles seems like a natural fit. Vue’s single file components are an archetype here.
(Here’s a video on CSS-in-JS I did with Dustin Schau if you need a primer.)
Brent Jackson thinks you should definitely learn it, but also offers some pragmatic points on what it does and doesn’t do:
What does CSS-in-JS do?
- Let you author CSS in JavaScript syntax
- Colocate styles with components
- Take advantage of native JS syntax features
- Take advantage of anything from the JS ecosystem
What does CSS-in-JS not rid you of needing to understand:
- How styles are applied to the DOM
- How inheritance works
- How CSS properties work
- How CSS layout works
CSS-in-JS doesn’t absolve you of learning CSS. Mostly, anyway.
I’ve heard lots of pushback on CSS-in-JS in the vein of “you people are reaching for CSS-in-JS because you don’t understand CSS” or “You’re doing this because you’re afraid of the cascade. I already know how to scope CSS.” I find that stuff to be more poking across the isles that isn’t particularly helpful.
Laura buns has a wonderfully two-sided article titled “The web without the web” part of which is about React and CSS-in-JS:
I hate React because CSS-in-JS approaches by default encourage you to write completely self-contained one off components rather than trying to build a website UI up as a whole.
You don’t need to use CSS-in-JS just because you use React, but it is popular, and that’s a very interesting and fair criticism. If you scope everything, aren’t you putting yourself at higher risk of inconsistency?
I’ve been, so far, a fan of CSS modules in that it’s about as light as you get when it comes to CSS-in-JS, only handling scoping and co-location and that’s about it. I use it with Sass so we have access to mixins and variables that help consistency, but I could see how it could allow a slide into dangerous too-many-one-offs territory.
And yet, they would be disposable one-offs. Code-splittable one-offs. Everything exists in balance.
Laura goes on to say she likes CSS-in-JS approaches for some of the power and flexibility it offers:
I like the way CSS-in-JS gives you enough abstraction to still use tricks like blind owl selectors while also giving you the full power of using JS to do stuff like container queries.
Martin Hofmann created a site comparing BEM vs. Emotion that looks at one little “alert” component. I like how it’s an emotionless (literally, not referencing the library) comparison that looks at syntax. BEM has some advantages, notably, requiring no tooling and is easily sharable to any web project. But the Emotion approach is cleaner in many ways and looks easier to handle.

I’d like to see more emotionless comparisons of the technologies. Choice A does these three things well but is painful here and here, while choice B does these other things well and solves a few other pain points.
We recently linked up Scott Jehl’s post that looks into loading CSS asynchronously. Scott’s opening line:
One of the most impactful things we can do to improve page performance and resilience is to load CSS in a way that does not delay page rendering.
It’s notable that an all-in CSS-in-JS approach gets this ability naturally, as styling is bundled into JavaScript. It’s bundled at a cost. A cost to performance. But we get some of that cost back if we’re eliminating other render-blocking things. That’s interesting stuff worthy of more data, at least.
I might get my butt kicked for this, but I’m a bit less interested in conversations that try to blame CSS-in-JS for raising the barrier to entry in the industry. That’s a massive thing to consider, but we aren’t talking about shutting down CSS here and forcing everyone to some other language. We’re talking about niche libraries for certain types of projects at certain scales.
I think it’s worth taking a look at CSS-in-JS ideas if…
- You’re working on a component-heavy JavaScript project anyway.
- You’re already co-locating templates, functionality, and data queries.
- You think you can leverage it without harming user experience, like gaining speed back elsewhere.
- Your team is comfortable with the required tech, as in, you aren’t pushing away talent.
Max Stoiber is an unabashed fan. His post on the topic talks about the confidence this style brings him and the time he saves in finding what he needs, both things I’ve found to be true. But he also thinks the approach is specifically for JavaScript framework apps.
If you are using a JavaScript framework to build a web app with components, CSS-in-JS is probably a good fit. Especially if you are part of a team where everybody understands basic JavaScript.
I’d love to hear y’all thoughts on this in the comments. Have you worked out your feelings on all this? Madly in love? Seething with dislike? I’d be most interested in hearing success stories or failure stories on real projects.
I for one am totally unbiased toward it, on the other hand i think it is a good idea because it opens up a multitude of new opportunities.
Prefer normal CSS to make a simple way
If any large organisation chose to go with CSS-in-JS and then one day decided to go back to normal CSS. The process of extracting or recoding the CSS seems incredibly difficult. These types of irreversible decisions are very hard to make.
Great point actually, I never thought of it like that.
That’s a non problem. How many large orgs moved from a LAMP stack to something like React, and then want to go back? The websites I’ve worked on have moved from one platform to another to another every 4-7 years anyways.
@ Rocky Kev
It is a problem, if don’t want to do a complete rewrite. If you move rom LAMP to React you want a rewrite.
But if you want to switch logic without to rewrite the css, you are forced to rewrite (port) this as well.
I have some thoughts on this.
The best argument for css-in-js I can come up with is: Separation of concerns does not necessarily mean separation of languages. So separation of concerns might just as well be understood as an argument pro css-in-js. I felt the joy of this component-wise approach in react.
My other thought is that I still find it very important to use JS only when necessary. To always question if it has to be, and to always try and build sites that do not rely on js. Just like with Flash back in the day.
I have the resources a website consumes in mind. Not just traffic, but also power. With websites being 10x larger in average compared to 10 years back, I fear JS-frameworks are all too often used to make the developers work easier, without gaining that many advantages for the user, but instead bloating the site unnecessarily.
So the question could be: Which technology is really helping the cause and which is just comforting the developer and maybe even costs the user without need?
“I fear JS-frameworks are all too often used to make the developers work easier, without gaining that many advantages for the user, but instead bloating the site unnecessarily.”
You’re not alone in that concern. The focus is too much on tools that make building products easier. That’s not the same as building better products.
Two things I wish more engineers/developers would embrace:
1) Just because you can, doesn’t mean you should.
2) Less is more.
Tools are not a panacea. More and faster =/= Better Product. Unfortunately, that doesn’t seem to be something the industry wants to admit.
This current retcon that the separation of concerns was because CSS, JS, and HTML were different languages is so backwards. They’re different languages because they’re different concerns. They’re concerns that benefit from separating because frequently change independently of each other and can and should be contributed to by different types of developers.
There both horizontal and vertical concerns. Slicing only vertically will have just as many downsides as slicing only horizontally.
No thanks, SCSS with BEM as a convention is just fine, material uiis a perfect example of why I strongly dislike CSS in JS
I definitely appreciate the unbiased take. People should be allow to use the tools that make them effective. There’s a lot of hostility towards the idea of CSSinJS and a lot of time it feels like gatekeeping, which to me hurts the community more than helps it.
I don’t necessarily have an issue with the concept of your CSS being shipped in Javascript, but really dislike many implementations that change how you interact with the language.
The only CSS-in-JS that I have liked is Vue’s implementation as it still separates the concerns while I’m writing styling.
On the other hand, I am a ‘frontend of the frontend’ developer that is moving towards a more rounded frontend position so I get tetchy at people messing with my CSS format.
I love that CSS-in-JS only includes the necessary “declartions”. ;)
“It’s notable that an all-in CSS-in-JS approach gets this ability naturally, as styling is bundled into JavaScript. It’s bundled at a cost. A cost to performance. But we get some of that cost back if we’re eliminating other render-blocking things.”
Yes, some. But that some also comes with a very important IF. That is, IF anyone cares about performance (read: there’s time, budget and a priority of leadership).
CSS-in-JS always struck me as a modern tech twist on office politics. It gives the engineers/developers more (centralized) control, and anyone not in the inner circle, less control. It’s a cheap & dirty proxy for leadership’s/management’s inability to manage construction based on (traditional) markup + CSS + JS. The technology is fine. Perhaps not perfect, but nothing ever is. But it does require cooperation and collaboration. CSS-in-JS aimed to mitigate that friction but created other issues.
Humans and trade-offs. It always boils down to humans and trade-offs.
CSS in JS is an abomination and whoever decided it was a good idea should immediately be transported by helicopter to the sea and unceremoniously dropped in. It solves none of the problems it claims to solve, discourages DRY code and adds unnecessary complexity to the development process.
We use a component library based on Material UI in our organisation. One of the tasks we had to do last year was apply the new corporate styling that had been used in this component library in an Ember app. It took 10 of us 8 months to do something that would have been a copy and paste job had the team that made the component library resisted this ludicrous fad and written something portable.
I’ve now moved to a new team that uses the component library directly. Why do we need to wrap our app in a ThemeProvider component and then each of my individual components in a withStyles higher order component when a simple import statement would have done? Why are we getting javascript errors in our unit tests because we didn’t set all this crap up for every test? Why is livereload doing a full page refresh for every styling change? What exactly are we now capable of doing that would have made this trade off in effort worth it?
Anyone who thinks CSS in JS is a good idea deserves a hearty slap to the jaw and its replacement can’t come soon enough.
Man that felt good to write – thanks for giving me the forum to get that off my chest
Jonathan, how is css-in-js relates to this?
Seems like you had higher order components and decorators to manage styles, it’s not exactly common approach for css-in-js.
Please elaborate
Perhaps this should have been taken to a post about Material UI rather than CSS-in-JS in general. I’ve been picking on Material UI because that’s what we’ve had to use and because it’s a popular implementation of CSS-in-JS.
However, even without Material UI, with styling there’s still a need for global styles for things like fonts, color palettes, link styles, grid layouts etc. You should still want to avoid repetition as much as possible so might want to use things like mixins or helper classes to avoid this (perhaps a flex-column mixin/helper class for example).
For applying these things in CSS-in-JS, your options are:
1. Repeat yourself. Constantly. And hope that the shade of corporate red you’re using never changes.
2. Use providers and/or higher order components, which cause all the problems mentioned in my OP
3. You can add these to a kind of globalStyles.js file that you import into all your components (or maybe component style.js files if you’re doing it that way), which is still more work than simply importing them to the top of your stylesheet and letting them cascade. If not planned correctly, this can still lead to a need to override styles which is apparently one of the problems that CSS-in-JS sets out to solve with its insane level of component-specific scoping.
4. Just use CSS (or SCSS or whatever your favorite preprocessor is).
Personally, I’d opt for option 4 as with any of the other options you may as well have used CSS and you’d be able to port your styles to other projects too.
It is a problem only of popular runtime CSS-in-JS like Emotion or Styled Components.
There are zero-runtime CSS-in-JS solutions, which uses Babel to extract CSS from JS into the static CSS file and use this static CSS sile as CSS Modules. Perfect performance, compatibility with all CSS tools, with keeping CSS in the same JS component file.
https://github.com/4Catalyzer/astroturf
https://github.com/callstack/linaria
https://github.com/lttb/reshadow
i dont like css in js. there needs to be some kind of tag inserted in css that pulls the required css for the component.
I think, for me, the #1 argument I’ve made is the barrier to entry that it can create. Specifically, in a time where designers are becoming increasingly more technical and we have the rise of the “UX Engineer” type of role, many of those designers are already very adept at your basic HTML/CSS manipulation and authoring. Many have moved into Sass (like myself) and find it very refreshing to have a level of control and autonomy because of it. Then you have the next level of organization like BEM or SMACSS or SuitCSS…and those make it easy to organize your styles and build on top of them inside a hierarchy and with clear (hopefully) rules defined by your organization or product.
When you throw the variable of JS in there to people that might not be that comfortable working inside, let’s say, a React-based system, you throw in some risk. I’ve been in the scenario where I had someone working in our app that didn’t know JS syntax and was stuck for hours trying to get something to work. Another case where someone ended up breaking something once it hit production…so there are inherent risks.
Everyone should be open to learning, but forcing one or the other is not the answer. I think linked stylesheets are still the way to go especially when it’s easier to set up environments that can build with Sass or Less or Stylus, but there are absolutely merits to CSS-in-JS…the most notable being direct manipulation alongside the JS. I find that to be the useful stuff, like doing state-specific things that might be more trivial or specific to the component rather than writing those into my Sass library.
I kind of agree with Jonathan Steven’s comments above, but I’m opening up to the idea just a little bit more than I was a year ago…but still very hesitant to surrender directly over to CSS-in-JS as the first choice or the only choice. I wish a lot of teams would stop jumping straight into it for the same reasons that he listed. You pigeon-hole yourself in the future should you decide to make larger changes or even some simpler changes. At least with like a Sass library, we have the power of imports and can encapsulate components and layouts (to me) easier.
I am relatively new to JS and in the beginning I loved the idea of CSS-in-
JS. As I have used and learned more I am moving away from so much CSS in JS source. I think a default better approach in global CSS/SCSS and maybe small sparse tweaks in the JS. But it also may depend the project, and selected the right tools for the perimeters of the project.
@Chuck Smith that’s basically what I’m referring to. There really should be a global-level of control and then if you need special tweaks at the component-level, then CSS-in-JS makes sense. Especially for managing state-level stuff so you maybe don’t have to manipulate the DOM to change or add modifier classes.
Why not both?
Have a design system of established globals, utilities and defaults in vanilla CSS for the UI proper, and then extensions of CSS-in-JS for state managed UI changes, that way achieving a balance of graceful degradation when a user either cannot load JS or has it turned off. Also, if you have to ever decouple the CSS from the JS for whatever reason, it doesn’t turn into a very heavy technical debt, it is just transferring those styles back into the design system’s ecosystem.
A great approach. To put it another way: absolutely, there’s a lot of value in building the equivalent of”user agent” styles into the component and tightly coupling those.
I don’t consider Vue or Svelte’s single file component style scoping to really be CSS-in-JS. Sure it is behind the scenes, but it only deals with scoping and it doesn’t prevent you from using SCSS or Stylus (just like CSS Modules), and it presents a far lower barrier-to-entry for designers and others who primarily know HTML and CSS.
I think one mostly unspoken issue with CSS-in-JS is it’s just harder to manage a large scale design system cleanly with it as far as I can tell from seeing people try and use it. Sure it’s possible to do it well and cleanly, but it adds one more surface of knowledge needed to properly work on a project and documentation for whatever combination of CSS-in-JS frameworks and approaches you are using. This inevitably leads to more complexity and people breaking from consistent or best practice approaches.
The barrier to entry part is a bigger deal than I think we give credit. There are people out there who dedicate their learning to accessible, performant, and well thought out HTML and CSS, and they shouldn’t need to learn JS just to contribute to large web applications. Not when we have newer and better frameworks than React like Vue or Svelte.
And this is why I mentioned barrier to entry. I know you’re big on Svelte now, but Vue has the same idea where you can better separate these 2 concerns and keep things a little more, I guess, kosher. And your point about systems at scale is the #1 reason I don’t like CSS-in-JS as the only solution. Again…it has its perks but I think the cons far outweigh the pros. Compared to pre-processing and compilation or vanilla CSS.
Isn’t the cost of css-in-js is componentize any reusable css into js which leads to far more js to download?
@Sergey there lies the irony with CSS in JS…and one of the things I’ve been thinking about when it comes to the core idea of CSS-in-JS as a performance win.
Yes to all. Especially your point re: Vue’s single-file-components not being CSS-in-JS, at least as far as “developer experience” goes!
Until recently I wasn’t in the need of using css-in-js. I work vith vuejs’ single file components and their css modules.
But recently I needed to calculate values so I needed to build a styling object. Just to hit the wall when I needed to style pseudo elements and needed to use media queries. Both not possible as far as I know.
So this comes on top of the inconsistency problem.
I do see the advantage of CSS-in-JS.
The problem i have now is that ill need to learn Javascript and React to use it.
Hoping it will help with website performance and work pace.
Normally i have to go onto a website to manually create Critical Path styling every time i make updates on a web-page.
I heard CSS-in-JS and/or React can sort out this problem.
Thank you for the article, was a nice read.
CSS-in-JS does seem most prevalent in React-land, so that’s fair, but all the major players (e.g. Emotion) either at least claim to be framework agnostic or have versions of them that work with other frameworks.
But if it’s anything like how Storybook works with multiple frameworks, at its core the design thinks like a React app and a React developer.
CSS-in-JS seems to exist because React does not have an in-the-box way to add CSS in JSX files. It took me a long time to make that realization. Coming from Vue.js where single file components can also include CSS as a first class citizen, the CSS-in-JS schism seems like a temporary thing that will last for as long as React lasts. Who knows, how long that will be.
Honestly, its really about picking the right tool for the job. Simple plain CSS is the greatest and most optimal choice you can make. Nothing is faster, more optimal and more controllable. Anything else is pretty much a trade off.
Processors – give you some maintenance capabilities, but you loose sense of efficiency and gain a set of problems like needing build changes, extra processing, get into XXXL selector hell and many more.
CSS in JS – SSR rendering has issues, optimizing painting is has issues, code duplication is its own problem, styling consistency and etc. On the other hand you gain fast iteration by large teams over long time, maintenance is easier once you have all code for component in one place and etc.
Entering the fray a bit late here, but I just thought I’d add a few more points to the negatives for css-in-js, which in my opinion has too many drawbacks for most projects. If you want to use JS as a preprocessor, fine go ahead, but as a runtime to be downloaded over the Internet it’s an anti-pattern.
I’m glad you mentioned limited distribution. But IMHO, this is the reason of reasons against CSS-in-JS. There is to date still no consensus for the particular library to use. So even if “everyone” started using them, reusability of CSS is atrocious. It’s especially bad when prototyping. Sometimes I just want to paste a damn form on the screen that looks ok!
I would actually remove “more code” from the CSS side and swap it over to JS. SASS/POSTCSS/LESS are not runtime, but they can solve most issues of code repetition and elimination. The only area CSS-in-JS wins here is in lazy loading. But this is now easy to do with external CSS and Webpack (and I assume also with Rollup/others).
The reason “more code” should be “added” to css-in-js is because the browser has to download and parse the full Javascript (which will be significantly larger) in order to render anything. If you have a vanilla SPA with a single div called “root” it won’t matter, but if you do it right and either have Isomorphic or static (Gatsby, etc) initial rendering, your page will display much faster with traditional CSS. That’s because it only needs to download the html and css (much less code and parse time) to display the view.
namespaced code also belongs in the traditional CSS column because of CSS Modules. With all due respect to Chris who I know wants to be a peacemaker between the parties and justifiably try to be inclusive, this is 2019 and this argument has lost all it’s weight. You might say well it doesn’t do that out of the box, but then does CSS-in-JS beyond the style tag?
Browser caching (without complex service worker setup) and HTTP2 aren’t mentioned. Standard CSS has had that out of the box since the beginning of (CSS) time. Separate CSS also works better with HTTP2 and parallel requests.
Lack of convention. This is another huge problem. as each library has a different convention/syntax. Most projects that I’ve seen are a hot mess of CSS mixed all around the same file as the application logic. There are some who get used to this and say “it’s a breath of fresh air”. Who are these people and do they write much CSS? What can be easier than having a screen split with a CSS file on the right and the App on the left?
Last but not least the sister problem of “HTML in JS” as the primary vehicle for the visual aspect of components. Did we forget that CSS already has components? That’s right, components are built right into CSS. Here’s an example:
Why did this style of writing CSS classes fall out of favor? Fear of the cascade and anything global. As a software engineer, you’re taught and biased to minimize global variables as much as possible from the beginning. But as someone who began by designing magazines and catalogs in QuarkXpress, Pagemaker and Indesign (where branding and style is very unique to each product) its clear to me why CSS was designed the way it was.
Does that mean some of the newer ideas coming from software engineers who’s expertise may not be design aren’t valuable? Of course they are, and many of the issues they raise are justifiable. But we need to use our brains and learn from the good parts, not just resign ourselves to start using and pontificating whatever the hip new thing. Let’s not forget, some of the most respected people in the web community tend to be software engineers at big companies, and as a result have louder voices. We unfortunately don’t have enough Jen Simmons’s or Rachel Andrews on the creative side to balance it off so we need to think and be diligent (and yes try it first) about what we choose to embrace.
To me this is the type of mental midgetry I expect from people unqualified to write a single line of HTML. Apologies if that sounds harsh, but it’s called separation of concerns. HTML for what things ARE — semantically, grammatically — CSS for what things look like. And JavaScript? That’s for enhancing an already working page. At least for any normal content-driven website.
But no, people who never embraced semantics, see nothing wrong with sleazing endless presentational classes into their pages (see “bootcrap”), pissing on caching models from so on high you’d think the almighty just got back from a kegger, and in general failing to understand or embrace the concepts under which HTML and CSS were created or why they even exist!
It’s no different than how 99% of the time you see style=”” and 100% of the time you see , what you’re really looking at is developer ignorance, incompetence, and ineptitude. No different from when you see people derp a page out starting with a H5, or using innerHTML, or any of the other “well screw good practices” nonsense that seems to be the bread and butter of the ignorant scam artists with their “JS for nothing and your scripts for free”
That ain’t workin’, that’s not how you do it.
Even though your comment is so rude, I’m glad the moderators let it exist as I’m a big believer in free speech (at least until the point that it bullies an entire group(s) of people or someone who wishes to stop, then count me out).
.
If you even meant to reply to my comment (you’re hardly intelligible and don’t take on any of my points other than the use of CSS components) it’s funny you would assume that I don’t have much experience. While I “started” as a Graphic Designer, I’ve been coding websites since 1997 amigo! Well before CSS existed, with HTML 3, Netscape Navigator, CGI, ASP (original), then PHP, jQuery/vanilla JS through to the present with React, Angular, backend, frontend, ops, etc. I’m a full stack developer who has built and worked on many high traffic products from startups to enterprise. Most importantly, through it all I have never stopped paying attention to changes and new ideas. Not to toot my own horn, but I would think I’m qualified to at least have an opinion on the subject.
Listen if you will, don’t if you won’t, but if you want my attention, at the very least you better have a rational argument for or against something I’ve said. All I can see is it appears someone is having a bad day and feels semantic classes are the pure expression of evil… but won’t even provide an argument for why. I don’t see anything refuting the current state/mess that css-in-js libraries and convention are in, nothing about the fact that browsers are built and tuned to work with external css files (and at this point of time) perform better, and most importantly, nothing positive to say to support ANY advantages of css-and-js over a tuned archetecture of traditional CSS and a modern workflow (e.g. CSS Modules, preprocessing, etc.). Just something about Bootstrap bad (which IMO uses the css class patterns I describe in an overly liberal way and causes too much coupling to specific HTML nesting).
Muddy code that resembles what it is supposed to do with longer, more cumbersome processes, higher financial and skill costs, just because you can do it that way even though you’ll never document it and just expect everyone to instantly know how to use it? Sign me up!
JS has become the proverbial hammer and developers see everything as nails.
One thing I would like to point out is Future Compatibility.
With CSS you never have to worry about updating libraries or be concerned about breaking changes.
We used styled components when they initially launched, over time they have released several updates. Some of them were breaking changes. There’s nothing wrong with updates and making the library better but it is a cost at the end of the day.
What we ended up doing? We left legacy components in styled-components and the new ones use plain old CSS. Slowly we’ll bring back CSS and get rid of styled components altogether. Because new developers take time to get productive with it (they call it annoying) and it is a cost they we really don’t want to bear as a small startup with so much already on our plate.
I personally like the idea of CSS-in-JS but then again, to each their own.
CSS-in-JS might be good idea since render blocking can be eliminated with it, but either way, it will not be easy for coding
The main problem I have with CSS-in-JS is that people are tempted to put all the CSS for a component in that component. It was not so long ago that we had to do a refactor because the creators of a website had decided to lock the font color and size down in the component and the customer needed a copy of the component somewhere else on the site, with a different color and font size.
After that, the customer decided to change the overall font size a little, and we had to do the same trick for all components.
So no, CSS-in-JS is not good or bad, it need to be implemented for a reason and that reason can never ever be “it’s popular” or some sh*t like “this is what the big companies do”
In my experience, using the CSS-in-JS does not preclude you from “building a website UI up as a whole”. An example, over the past 2 years, we have been migrating our CSS modules-based components to use Styled Components. Many of these components are used across the app (and in other apps as well). It has been a 1-to-1 conversion, with the benefit of being able to rip out className bindings required to handle conditional UI logic.
As for the baseless argument “… people are reaching for CSS-in-JS because you don’t understand CSS”, CSS-in-JS renders CSS in the browser which requires… understanding of CSS, at least from what I can tell. :)
Having said this, CSS modules are still excellent for handling global styles, and high-level components and wrappers that may not otherwise handle complex UI interactions.
I have used CSS-in-JS for the past 4 years, but also, I have used React, Vue and Angular (aka javascript frameworks) in most of the applications I have worked on. I admit, I am biased towards the beauty of working with react, and all the practices the community has made available and popular for it.
CSS-in-JS was a life changer for me. And it really doesn’t break any of the styling paradigms, the real benefit is more for structuring and separating styling concerns across components, that is why styled-components or emotion are made for, it really helps when structuring a folder/component structure in any application.
I’d also say Vue is not CSS-in-JS. The only thing resembling CSS-in-JS when working with vue single file components, is that you don’t have a global stylesheet and it gets scoped under the hood (if you want to) – besides that you use regular CSS syntax with familiar nesting syntax etc (when using SASS or LESS).
Reaearching the topic I also see potantial and advantages in CSSinJS. I guess my initial frustration comes from the way material-ui requires you to overwrite styles in components. After a full week writing styles this way still triggers me…
Well I agree that not all Web Site developers are doing it as a living but helping others to write Web Sites for family reasons/ or small clubs etc.
So I agree that I have no time to learn Javascripts but have no problem with Javasript Libraries, being to help some areas.
Brianran
Great article!
Coming from a traditional CSS/Sass background; once I began using React the CSS-in-JS route via styled components made perfect sense to me. I really enjoy how everything is localized within the component and easily moved around if needed. I was once 100% apposed to mixing style with function, but, people change.
That said, it can get a little messy once a component starts to grow. But at that point I figure the component is trying to accomplish too much and I refactor it out to more focused components.
I am still working my way though what will be my “perfect” approach to styling within React, but for now I am happy with CSS-in-JS.
Also, separate thought here on top of my first one.
Jen Simmons mentioned something about CSS-in-JS which I want to take a step further. CSS is “cascading style sheets,” but when you use it in the CSS-in-JS way, there is no “style sheet” anymore. You are essentially inlining everything and there is no more sense of hierarchy like you’d have with a preprocessor-based approach or a really well-documented CSS library. But that’s the thing: there is more than likely no central library with this approach. You can do one, but really I’m not sure this approach is actually able to be called “CSS” because there is no cascade…and I guess there isn’t really a sheet either.
Thoughts on that?
Agreed, Specificity disappears entirely. With Vue I can override UI framework component styles by simply using specificity. With React and Styletron I have to hope that the developer exposes an adequate api for overriding styles.
If you’re concerned about scoping just write nested scss. Problem solved.
css-in-js doesn’t absolve you of writing clean code by the way.
To me it looks like a big excuse of js devs to not bother with css.
The benefits of the cascade far outweigh the specificity of the component approach
(as usual the biggest strength of something tends to be the biggest weakness as well).
But you need quite an understanding of css to get it right.
So my question is should js devs learn to css?
I’m with you here, it just seems like a way for JS devs to take over yet another thing that their language doesn’t need to do, to avoid learning another one.
I use CSS Modules in React but I love the concept of CSS-in-JS in a single file component such as Vue and I will be using emotion for my next project.
My point for CSS-in-JS is that if you have a very large modular application with hundreds of components, having shared .css/scss files becomes a tech-debt as if the css architecture was not properly organized, it will be hard to discard unused css.
With CSS-in-JS if you refactor your app or discard whole feature, the whole CSS goes with it painlessly, reducing bundle size and preventing things to break.
CSS-in-JS to my React and Storybook oriented mind feels like a great fit. I first got introduced to the concept through JSS, styled-components is sort of an in-between. I haven’t tried Emotion yet. But all these libraries are created for the component world, if you’re not working creating apps with React/Vue or any of those libraries then you probably have no use for CSS-in-JS.
And since they’re mostly created for component libraries, then it’s a question of whether we should encapsulate component styling in a single component file, or allow them to be separated into two chunks — one in JS folder, another in the CSS folder.
Concerns about maintainability seem more like a theming concern rather than component styling for functionality concern. When it comes to style organization I made it a point to separate theming and component functionality styling. Semantic UI, for example, made it a point to make no stylistic opinion on theming and keep theming a separate thing altogether. The same goes for the insanely popular Bootstrap and other frameworks. Then it makes a case that perhaps certain style rules pertain to the core of the component that won’t change depending on the theme, and certain style rules can change depending on the theme.
The rules that won’t change can live in the same component file, 1 component 1 file. That leaves theming files separated anyway because they should be. It doesn’t make sense for me to go to two places just to change one thing — Redux is already giving me flashbacks, no!
The more important distinction to make is when does something counts as “theming” and when does something don’t. Now that needs some practice and wisdom that I wish someone can beam into my head right now, and that will be the source of where the messiness comes in.
But let’s be honest, if we’re in a project where we can’t separate form vs function or the product isn’t mature enough yet to see the distinction or the style is the function, then any amount of overengineering is gonna hold the project back. “Overengineering” in such case to me would be going back to the days of SASS or LESS and keep two separate directory trees for a single component, while “overengineering” to others may mean new technologies that are unnecessary to deliver the product.
Why not both css and css in js? I style the vast majority of my sites using a homegrown utility class library. But container queries work much better in js, so when the utility library doesn’t have a utility and the feature isn’t general enough to warrant an addition to the lib, then I use css in js to solve the problem. While I heavily prefer plain css, it’s not like we have to choose one or the other.
I think CSS-in-js has its place in component based architecture, and there are pros and cons. You just have to choose the right tool for the job. I think there’s definitely an element of hype around some CSS-in-js solutions where people use them trying to solve a problem they don’t have.
However, I’d argue that most of the cons around scaling and code re-use can be worked around and implemented easily enough, eg using preprocessing, mixins, component re-use, global utility classes etc.
Of course whether or not that’s how it pans out in the trenches and whether devs will actually take advantage and avoid code duplication is a different matter, although the same could be said of large BEM codebases.
Also, if anybody is interested, I started a kialo poll on this, apols for the clickbaity title…
kialo.com/css-in-js-is-a-great-idea-29721