You got your CSS in my JavaScript

Separation of concerns. You have your HTML over there, your CSS over there, and your JavaScript over there. Each should be as separated and independent as possible. Or so we’re told.

While CSS Zen Garden gave us a glimpse of a possible world where CSS could change and HTML never would, the reality—at least, in my experience—has been much different. Design changes often require both HTML and CSS to change. That’s because the fundamental structure of what we want to style also changes.

Likewise, for JavaScript. It interfaces with the document to allow for dynamic interactions for and from the user. For increasingly complex applications, JavaScript has needed to take on more and more work. JavaScript is used to load HTML partials (or entirely new views); it is used to manage application state; and it is used to manage data and decide whether it needs to generate new chunks of the page using a template system.

As you can see, with JavaScript doing so much, it should be unsurprising to see many frameworks move to using JavaScript as the crux of the application—to the point where the body may start empty until the application is loaded and can render the view.

The React community, with its large gravitational pull, is pulling everything into the land of JavaScript: HTML (in the form of JSX) and CSS (in the form of CSS Modules and inline CSS).

Some rail against this unified theory of application development on the purist grounds that each pillar of web development should remain completely autonomous.

Why declare CSS in JavaScript?

To answer that question, let’s consider the React approach. There’s a lot of talk about the virtual DOM but, to me, the big thing about React is its component-based approach to application development.

This component-based approach is very much in line with the SMACSS approach. They’re both trying to modularize an interface. Part of that modularization is the ability to isolate a component: to make it independent of the rest of the interface.

Making a component independent requires taking a chunk of HTML along with the CSS and JavaScript to make it work and hoping that other CSS and JavaScript don’t mess with what you built and that your component does not mess with other components.

At Yahoo!, we had a folder structure that looked similar to this:

/js/modules/modal.js
/css/modules/modal.css
/html/modules/modal.mu

React can essentially merge all of these into one file. For a given page, when you load only the components that you need, you load in only the JavaScript and CSS that you need as well. With these components now loaded, they can be used repeatedly without requiring any additional bandwidth. Again, this is very similar to how we did things at Yahoo! but we used YUI.

Whether you generate CSS classes or inline the CSS into the actual HTML won’t really matter for client-side-only applications. If you want to generate the initial view server-side then you might have some considerations about how to separate these pieces to allow caching, if that’s a concern. (Why wouldn’t it be a concern? Maybe you’re doing post-render client-side caching.)

http/2 and Web Components

Web Components are similar to React components in that they allow us to encapsulate HTML, CSS, and JavaScript into a single file. (Whether we choose to do that or not is another matter.) And http/2 allows us to ship these components individually without having to compile them into a large bundle like we’ve traditionally done.

What, me worry?

While some may rally against mixing CSS (and HTML) in with JavaScript, I’m not overly concerned. When using a component-based approach, bundling everything together doesn’t feel like a grand departure. Instead, it feels like a reasonable way to build a site.

Published February 21, 2016
Categorized as JavaScript
Short URL: http://snook.ca/s/1069

Conversation

6 Comments · RSS feed
Tommy Hodgins said on February 22, 2016

There has been some talk about CSS-in-JS on Hacker News today with a posting about Descartes.io over at: https://news.ycombinator.com/item?id=11143377

I think it's not the best solution violating the separation of concerns, but it's ~sure~ a lot better than abusing HTML as some kind of a go-between to make JS and CSS talk to each other!

I'm not sure which approach is cleaner: CSS-in-JS or JS-in-CSS. I made the JS-in-CSS work for me, but I'm a CSS guy, not a JS guy so maybe I'm biased ;)

Either way, I'm glad to see people experimenting and trying out new things.I can't wait to see how these (and other) experiments inform how the web evolves in the future!

Are you planning on releasing any experiments of your own in the realm of CSS-in-JS? I'd love to see what you come up as a mashup of the two syntaxes, based on your experience!

Sten Hougaard said on February 22, 2016

I Like the style of developing where content is seen as components/objects which holds both content, style and functionality. It's the way of object oriented development: each object/component has the knowledge needed to "live" somewhere, like in the DOM. In that perspective HTML, CSS and JavaScript are only parts being used give "life" to the object.

We (in the website building world) have focused mostly on those three parts but now start to feel the need for another way to view the way to construct websites as the web is growing into more (web)app style. Things from object oriented development world like inheritance and methods being part of each object start to make sense and frameworks like React offers that.

Have you seen the Yandex BEM system? Only the CSS part of it has gained respect outside Russia. I saw some videos where Vladimir Grinenko explained the framework and I was impressed with how well structured it is. Take a look at it here: https://en.bem.info/ and here http://youtu.be/2r72EjALq2s

Samuel Allen said on February 22, 2016

There are ways to create focused, semantic markup and CSS without violating the separation of concerns. Here's my approach using LESS: https://medium.com/@dehuszar/semantic-remapping-with-css-pre-processors-906ba1a9910c#.smpvjakm3

Rachel Nabors said on February 22, 2016

And let's not forget how interaction and animation further muddle the water: is animation a "display property" that should go in the CSS? What it it's interactive, reacts to the swipe of a user's finger? Maybe that animation should be put in the JavaScript. Oh dear, now how do we maintain consistency between the two? And how will we know where to look for them when we need to make changes??

As the web becomes more interactive, more reactive, the line begins to blur between content, layout, and behavior.

Liam said on February 24, 2016

Well, let me land my support to keeping CSS and JS separate. I mostly do design, and HTML/CSS, preprocessors. For years now I have been struggling with JS. I just don't get it. Maybe, I am dumb or maybe I just have some mental block do to my aversion to JS. I don't seem to have much trouble with a bit of Bash and Python. But this push to have designers code, and now having CSS in JS, is screwing me over and making me less hire-able.

Bramus! said on February 25, 2016

Whilst I don't mind combining all needed things (JS/CSS/MU) of a component/module/whatever into one file – they, after all, only work when combined – I don't like the React approach.

In React you can indeed define styles, but not using the CSS syntax we are already used to. The use of some specific selectors (combinators, to name just one) is therefor not possible with said syntax, leaving me as a frontend developer limited in my options.

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.