One important topic worth discussing when it comes to CSS-in-JS is the use of Tagged Template Literals (TTLs) to contain CSS syntax vs using Objects. I recently stated in another article “I personally can’t stand TTLs”, without providing any sort of qualification or rationale. I hadn’t realised this opinion was so controversial…

I had naively thought that everyone else shared my view that they were sort of hacky, and hence nothing more than a tolerable workaround to a problem that there was no better solution for. Turns out a lot people actually really like them, so in this article I’d like to address why I feel as though using Objects is a better approach to Sass syntax within TTLs, but really, it does just come down to preference and how you’d like your API to be.

I suppose the initial motivation for wanting to use Objects as opposed to Sass inside TTLs is that since I’m using JavaScript for my styling, it seems to make more sense to use plain JavaScript for all logic and abstractions, rather than writing code (and thus, logic) inside strings, which is essentially what CSS in TTLs is.

Nonetheless, consider the following pseudo-code utilising TTLs to contain some Sass syntax:

This pseudo-code may very well work with existing solutions already, but I guess the first thing I’d ask myself if I found myself doing something like this would be, why not just use Sass, since it looks identical? Aside from the benefit of the potential for scoped styles (using some bespoke Sass library, or even a naming convention like BEM, could also solve the issue of scoping), this article notes that other reasons why people may choose CSS-in-JS over Sass include:

Define your helper functions in regular JavaScript

Co-locate your CSS with your React components

Type Checking and Inline Documentation

Laziness!

These reasons may (or may not) convince someone that using CSS-in-JS is superior to using Sass, but it doesn’t necessarily explain why one would opt to use Tagged Template Literals containing Sass syntax for their API if they were to go with CSS-in-JS. Ok, sure, it resembles CSS/Sass, allowing you to maybe copy and paste some existing CSS/Sass code from somewhere else, and use a syntax that allows you to follow familiar styling paradigms etc, which of course are all fine reasons, but let’s consider for a moment that we’re using JavaScript and React here…

JavaScript, especially ES6 syntax and beyond, offers a plethora of neat ways to do things, which we can take advantage of. React also offers a plethora of neat ways to do other things. Since I’m using JavaScript to handle my styling combined with using React, my natural first port of call would want to be to utilise paradigms already offered to me by these tools.

So I’m initially thinking about things like JavaScript Objects, Arrow Functions, React Components, State, Props, Context etc…these are the concepts I’d want my ideal styling API to be based around. If my styling API were instead based around things like selector nesting, cascading, divs, class names etc (i.e Sass syntax inside TTLs), I’d need to worry about another layer of abstraction. And not just in terms of thinking either; either you or your solution would need to take your React Components and their corresponding state/props/context etc, and somehow map them to your Sass declarations, typically in the form of class names. A barebones journey of this in plain English might be:

(JSX) On this component, if props.someProp is true, add this class name (Sass in TTLs) On this component, if this class name is applied, add these styles

…this seems to be more or less what happens when you use TTLs to contain Sass syntax when using React (or indeed, if you were using regular CSS/Sass, too).

Consider the following code which would solve the exact same problems as the previous Tagged Template Literal example (i.e, apply the same styles to the same components when the same conditions are met), except utilising the aforementioned concepts (Objects, Arrow Functions, Components, State, Context etc…):

More or less the same thing is happening in both examples, in more or less the same way. For me, the latter example using objects, arrow functions, state, and context, etc is much more appealing. The journey has now become:

(JS Object) On this component, if props.someProp is true, add these styles

…removing the need for the additional layer of abstraction (i.e the second step). It almost feels like the holy-grail of APIs for styling React components; it feels clean, pragmatic and sensible. I also feel as though that when using the latter example, more useful information is conveyed (probably due to the removed layer of abstraction), and just looks nicer than the TTLs example (again, all this is just my opinion). It also allows your JSX to be much cleaner, too.

Looking at the proposed API, we’re not really dealing with CSS at this point anymore, there is no evidence of cascading, so I feel somewhat uneasy about referring to the solution as CSS-in-JS. It’s more like JavaScript Styles, or JavaScript Style Sheets (JSS…JSSS?). That name seems to have been claimed already (by a tool that is pretty good, mind you), so it’s probably more pragmatic to just continue viewing this as a CSS-in-JS solution, despite there being no cascading.

Conclusion

The only arguable downside to the proposed API using objects (that I can think of) is that it naturally pushes for inline styles to be used as opposed to real CSS, which some people see as a deal-breaker (I personally don’t take much issue with it given the other benefits). As important as performance is, I’d need to do some actual benchmarking to determine if there’s actually any perceivable downsides to using inline-styles at scale. The Developer Experience benefits gained are certainly perceivable in my book. In any case, I’m sure some wizard could take the proposed API and somehow find a way to generate real CSS from it if push came to shove.

If you liked this article, checkout these other relevant articles: