If you've been on the internet recently, you've probably heard of CSS-in-JS.
The technology has been growing in popularity recently but not everyone is a fan. Today, I'd like to demystify what it is and why I think you should be using it.
Now, if you're anything like me, when you first heard the term CSS-in-JS you probably thought:
Oh no... not another thing I have to learn!
I have good news though if you already know CSS, you don't really have to learn anything new. But wait, if you already know CSS, then why bother writing CSS-in-JS, doesn't that just add complexity?
Why I Write CSS-in-JS 🎨
CSS stands for Cascading Style Sheets. Back when CSS was created, we were building websites which were typically pretty simple by today's standards. At the time, the cascading part of CSS was super useful. Today, however, I think it ends up being a foot-gun more often that it is helpful. Think about it, can you remember every class name you used on your last project?
Now imagine working on a project with several other people. Writing CSS that conflicts with or overwrites someone else's styles is essentially inevitable. Techniques like BEM and SMCSS can help but you have to rely on all developers following the rules and as a project grows so do the chances that someone will slip up.
For me, CSS-in-JS and Styled Components in particular help save me from myself. I'm protected from my own mistakes by an API instead of by convention. CSS-in-JS allows me to focus on styling my UI without having to be mindful of overwriting CSS somewhere else.
The cascade can still be useful, however. With Styled Components, you can still take advantage of the cascade but it is limited to the scope of the component you're working on. You can have your cake and eat it.
Okay, let's say you never make mistakes. Are there any benefits to CSS-in-JS besides controlling the cascade. As it turns out, there are. CSS-in-JS libraries are responsible for how styles are injected into the DOM. They can track which components are rendered and only inject the styles required.
This means the user ends up downloading fewer bytes of code and will have a quicker time to first paint. Great success.
Have you ever wanted to remove some CSS from a project but you had no way to be sure it wasn't being used somewhere. With CSS-in-JS, this usually isn't a problem as styles are typically co-located with the component that relies on them. You'll never have to go hunting for the CSS that is affecting the component your working on again.
Most CSS-in-JS tools give you all the benefits of traditional CSS preprocessors too, including nested rules and auto-vendor prefixing.
What are the disadvantages of CSS-in-JS
All tech choices involve some sort of compromise and using CSS-in-JS is no different. The primary drawback of using something like Styled Components is the added complexity. First of all, it needs to be installed from npm. Not a big deal, but it is one extra step.
If you are sever rendering your code, you're going to need to install and configure a babel plugin to make sure your styles work on the first load too.
The other drawback of CSS-in-JS is that it just might not work for your particular application. If you're not using a front end framework like React or Vue, CSS-in-JS is probably not the right choice.
If you're in a situation where CSS-in-JS isn't a great fit, I highly recommend you check out Tailwind CSS. It is a utility first CSS framework that helps you build UI's rapidly. You don't get any of the benefits of CSS-in-JS but it may help you avoid some of the pitfalls of CSS.
As developers, our job is to solve problems using code. CSS-in-JS is a tool that helps us solve problems more efficiently and write code that should be easier to maintain.
If you've tried a CSS-in-JS solution and it didn't work out, that's cool too. Do what works best for you and your team.
Let me know if you have used CSS-in-JS and what problems it solved/caused for you!
Top comments (17)
I don't know if I'm just one of those legions of knee-jerkers, but I think that CSS-in-JS is a terrible idea, pretty much for all the reasons you think it's good.
It's ok with components I guess, and they're all the rage among front-end blog posts this year, but we're getting farther and farther away from the idea of a simple, usable web. The dream of the semantic web died because of things like this, and the replacement doesn't add anything useful to the world. It seems to me like short-term solutions to fix things that aren't problems.
If you need to do this, I think you've got CSS wrong in the first place.
I have two things to add to your comment. Firstly, you're right, CSS in JS is a really great fit for the component model. It's also worth noting that that splitting a UI into small reusable components isn't a trend that is going away anytime soon. Not only is it great for simple blogs, it's nearly essential for larger more complicated apps. The semantic web is alive and well in the modern world of development. CSS in JS is a tool which ultimately ends up producing CSS that the browser interprets. If it is the right tool to solve a problem, why be so quick to shoot it down?
Secondly, I've been writing CSS in a professional capacity for the best part of a decade, so I don't think I've "got CSS wrong". CSS has limitations and choosing vanilla CSS over some other tool will have advantages and trade offs.
I guess my point is that as engineers, our job is to pick the best tool for the job. If that happens to be CSS, great, if not, pick something else that works. For me, recently, CSS in JS has been the right tool.
We ended up doing a minimal baseline CSS that's very rarely modified these days, and then going component-based for the rest of the styles. It turned out to be the right tool for the job. Development is fast and flexible and performance is good. Not to say there aren't drawbacks, but for this project they definitely are overshadowed by the benefits.
When I'm doing a small personal project, I end up usually defaulting to a purer CSS based approach and not going for inline styles, since they're not so difficult to manage.
First of all, somehow this whole comment mostly read like how a politician would answer a question. That is, not actually provide insight, but talk meta. I'm not trying to be ad hominem, I'm just saying how it felt to me.
From my experience it almost never actually works out like that. Write something reusable and next time it won't actually be usable like that.
One of your original points was that the browser only gets to interpret something it actually needs... Which brings me to the question: How does it save anything if now, instead of getting CSS rules by a .css file, it now gets CSS rules in a .js file? Also, how is your filtering logic on what CSS to actually present to the browser better than the browsers logic of parsing a CSS file, picking out what it actually needs?
I am inclined to trust the browser with being able to pick apart CSS that I wrote in a performant way (it's written in C++ too, and had hundreds of pairs of eyes on it in it's lifetime) rather than trusting me being able to present the right css to the browser at the right time. Also, I'm not sure but I assume it sets style attributes on the fly? Which would also not allow the browser to pre-parse and optimize CSS that was given to it in advance.
Honestly, this way of phrasing it basically implies that it's a non-discussable given that it's the right tool and that critics are just trying to shoot down something they're ignorant about.
I don't know, I've been writing CSS for like 13 years and while I do think I am quite proficient in it (by now), it doesn't mean this knowledge is a hard overwrite of everyone who disagrees with me. I mean, I disagree and think you've got CSS wrong, but more on the technical side. I elaborated above why.
There are usually no consistent hooks so regular stylesheets will have a very difficult time affecting the way something looks. Why is that a problem? It's a problem for accessibility - if I want to add a custom stylesheet or use userstyles or anything, suddenly it's a whole lot harder if not impossible.
Just have to say loved how you replied this question.
I don't believe that changing the nature of CSS would help writing more maintainable code.
And, that's what I love about the single file components in Vue for the reasons you specifically mentioned.
I am generally weary of intermediate layers as bugs/entropy/updates whatever. Vanilla HTML/CSS/JS done well can be left for years. Can be hyper fast/simple clean (but usually we are rushed). Copy pasting a stylesheet & editing a few variables is as fast as it gets. Multiply the extra steps by 50 sites or something & it adds up.
I like CSS because it is a backstage dumpster where you can 'hide' things, no harm.
It would be very nice to have the features CSS in JS has however & I understand the use cases (if you are running a complex site with lots of ppl it is very good).
I think both have their place (this is probably now the controversial position).
Aren't all the tools we use to build websites essentially an intermediate layer? Unless you're writing byte code of course. I work at a product company so don't have the issue of setting up project after project, but I can see that becoming a pain if it's not automated.
You're totally right that both tools have their place though!
Yes, they are all intermediates.
Imagine it like a sandwich. I like bread & cheese. Maybe a touch of butter. Fresh, warm organic bread. Simple, reliable. Focus on the cheese which was from cows that live in the mountains above the mosquito line.
Some people prefer a little more filling.
Each to their own (somewhere in between is usually good).
I agree with your reason
But I don't think the solution is always js since it already handle a lot of responsibility, separate CSS with js has its benefits like bundle size, performance, code test etc.....
I personally use CSS module in my project
Which I think is the best of both world
I totally agree that generating a separate CSS bundle from JS is an easy performance win. Thankfully, with most CSS in JS tools this is easy enough to do.
I had a chance to use CSS modules this weekend and they're really great!
This is a nice summarized article thanks for that. Can I give a shout out to emotion.js which does almost exactly what styled-components does and occupies less space.
Before JS I used to involve myself with only CSS. After being introduced to styled-components I have found it impossible not to use on React projects. I still try to adhere to semantic-ui HTML principles as much as I possibly can when using styled-components and it provides excellent support for this.
This is why SASS got created I guess.
Damn, Paul! Really wanted to stir things up this weekend 😂
I'm both shocked and delighted with how it turned out!