DEV Community


What are "HTML-CSS-JS" and "CSS-in-JS", anyway?

bhaibel profile image Betsy Haibel ・3 min read

Yesterday afternoon, an early-career developer I know DMed me to ask: "What are people defining as CSS-in-JS, anyway?" They had seen a lot of the debates flying around the internet, but didn't know how to engage with The Discourse, because no one was bothering to define terms. As I thought about how to answer them, I realized... "CSS-in-JS" is a large, umbrella term! There are a lot of different "CSS-in-JS" techniques out there, and some of them are closer to "traditional" HTML-CSS-JS approaches than others!

A lot of the HTML-CSS-JS vs JS-JS-JS debate is rooted in historical context and feelings rather than precise technical details. I don't think that trying to turn it into a purely technical discussion is a good idea, because there's so many other social dynamics in the room. But I also think that the technical aspects of the discussion will be healthier if we bother to define our terms. In that spirit, I'd like to talk about some specific front-end strategies I've observed.


From breaking these strategies down, the best working definition I can figure out of CSS-in-JS:

any technique which uses JavaScript to apply styles universally, as opposed to applying styles in response to user behavior.

"Separate file" CSS.

Generally not considered CSS-in-JS

CSS is developed in .css (or .scss, or .less) files that are maintained separately from .js files. In development, they are generally be kept in a separate stylesheets directory. These CSS files might be preprocessed from several small files into a larger CSS bundle, or they might not. If the CSS uses component-oriented techniques, developers use BEM or another naming convention to ensure that component-level styles stay component-level.

Web components and Shadow DOM

Generally not considered CSS-in-JS

No strong conventions around "where" the CSS is kept yet here because it's a young technique! But in this style, Shadow DOM style isolation is used to ensure that component-level styles stay component level.

Component-level CSS with informal scoping

Generally not considered CSS-in-JS

CSS is (usually) developed in .css/.scss/.less files that are maintained in the same directory as other component files (e.g. HTML, JS, JSX). This strategy also covers .vue files that do not use the scoped attribute in their style block. These styles are preprocessed into a larger file for delivery, but no data attributes or "roboclasses" are added to enforce component scope. Instead, developers have to use BEM or another naming convention to ensure that component-level styles stay component-level.

JS-applied utility classes

Sometimes considered CSS-in-JS

A utility class framework like Tailwind or Tachyons is maintained in a separate file. All components are rendered by JS, and use that JS to decide which utility classes to apply to HTML elements within the component.

Component-level CSS with JS-enforced scoping

Sometimes considered CSS-in-JS

In this frontend strategy, CSS is used for styling in conjunction with component files OR is embedded in those component files, .vue style. The Vue scoped attribute or a plugin like React's styled-components is used during processing to add a "roboclass" prefix to the component's styles for scoping. This "roboclass" is applied during client or server rendering of the component, so this strategy requires that JavaScript be used for template rendering.

JS-applied inline styling

Pretty much always considered CSS-in-JS

All components are rendered by JS, and use that JS to decide which specific inline styles to apply to HTML elements within the component. "CSS modules" fall into this category.

I'm dashing this post off quickly before leaving for a month-long trip. My list isn't intended as exhaustive and my explanations may not be as clear as I'd want them to be in a more polished post. I'd really appreciate it if y'all could help fill in things I've missed or handwaved, so that this post/discussion can become a strong resource for folks who are confused by CSS-in-JS discourse.

I'd appreciate it if y'all kept your opinions about these technologies OUT of the discussion. I intend to write a follow-up post about what I perceive these technologies' strengths and weaknesses to be. I'll welcome your opinions in that comments section! But right here, I'd like to keep it to definitions, to maximize this post/discussion's usefulness as a resource.

Discussion (4)

Editor guide
ben profile image
Ben Halpern

Great little writeup. Folks definitely talk past each other in this debate and lots of folks on the sidelines rooting for some approach without really knowing the details.

One interesting thing about all of this is the sense of FOMO I felt about 3 years ago from people who were scared to miss adopting CSS-in-JS as if everyone was about to stop writing CSS tomorrow. Fast forward and we're still sort of in the same place. Interesting evolutions on both sides of this coin and new ideas to consider. It's okay to sit back and let things play out without getting to riled up.

maxwell_dev profile image
Max Antonucci

As someone who was participating a little in this kind of discussion, I still wasn't fully aware of the different nuances and differences in the degree of CSS-in-JS one can write. This post is great for starting to clear all those up!

chrisachard profile image
Chris Achard

Nice writeup - it can definitely be confusing with all the different possible ways to style something - plus all the different libraries that now do css-in-js (and keeping track of what is what).

I used to worry that I wasn't doing it "the right way" - but then realized, that no one is really doing it the "right way"! It's mostly all circumstantial: whatever works the best for your workflow and team.

sebbdk profile image
Sebastian Vargr • Edited

CSS-in-JS conjured up the same horror from when i saw JSX.

Next we will see animals and humans fornicating, people in Denmark wearing colors, Trump making sense, spaces instead of tabs, what a chaotic and perverse world this would be!

Having pondered these ideas more these days, i kinda like them.
Maybe it was just too radical to accept initially. :D