Style as a Function of State

It’s been almost 2 years since Christopher Chedeau aka Vjeux initially introduced the concept of CSS in JS. A lot has happened since then and tons of fancy libraries have been released, all (of course) pretending to solve all the problems once and for all. But don’t get me wrong. I am not criticising these solutions at all. Far from it! I even built two solutions myself. So, if at all, I should be blamed for pushing yet another CSS in JS solution.

Nevertheless I am here to share my thoughts about CSS in JS techniques and what I believe to be the most important feature of using JavaScript for styling purpose.

Background

Yet, we somehow still struggled to keep the UI in sync with our state. Until, at least for myself, libraries like React or even whole new languages like Elm got introduced.

v = f(d)

The idea is simple. You pass your relevant data in, and get a declarative representation of what should be displayed out. The data most likely some consists of parts of your application state. Here’s a really simple example:

Now assume our initial state sets follower to 0. We will see the following text in our app.

You got 0 followers!

Luckily, we eventually managed to get some people’s interest and got a neat amount of 20 followers. As the state updates the view automatically also rerenders. It receives the new state and updates the DOM to output the following text.

You got 20 followers!

Intense magic, huh? Actually not. Using this very simple principle, we are able to compose complex state-aware UI that ensures to be always be in sync with the state.

style = ?

Traditionally, we would have different CSS classes with each setting the color property. e.g.

Very basic. Now we have to add these styles to our view by simply referencing the className. The updated view will look something like this:

This works quite fine and was not too hard anyway. But… let’s say we now want to display the text in a nice yellow (remember, with yellow text comes great UX) if we have 10–19 followers.
We would most likely add another CSS class and link it to the view, actually making the className expression even more verbose. You might now get why this often does not scale well and is quite hard to maintain. And always remember, this is just a very basic and simple example, far away from complex real-world application styling.

But Why?

Not only does this create some kind of dependency, but first and foremost does it contravene with the reactive and pure nature of our view itself. Instead of updating the style, we have to switch references to static assets?

s = f(d)

So how comes we still use static style assets which are totally unaware of the current environment? Imagine our styles would be functions and would automatically update if the state changes as well.

Actually that’s quite easy. Consider the following example:

Pretty cool, isn’t it? Every time the state updates, we now can ensure that the style gets updated too. Sure, if we return the wrong style object, we still might get the wrong styling applied. It’s more about the concept itself and the theoretical idea of style as a function of state. Yet, I believe it comes with several benefits and is much easier to maintain, debug and understand. Also refactoring and adding new style is rather simple compared to the traditional way. Also it is functional and pure (at least if you only use pure functions) which makes it predictable as well as kind of reactive. After all, it ensures that the correct styles are added at any given point of time.

But inline styles suck!

Truth is, with CSS behind, the solution would be even more useful and not restrict the use cases and features. Luckily, I already built a production-ready version of this concept. It’s called Fela. This post is not about promoting Fela, but I am still asking you to at least try it and form an opinion. (Feedback is highly welcome)

Fela

Renderer
The renderer is the most important part of Fela. You can think of the renderer in Fela as the store in Redux. Also, similar to Redux, you only have one global renderer which gets passed down the component tree via context (using a Provider component).
It ships APIs to render all kind of CSS stuff including fonts, keyframes and static/global styles. It also diffs and caches styles in order to return the minimum amount of CSS, as fast as possible.

Rules
Then there are the so called rules. They represent the style functions from above and accept any valid style object, including pseudo classes, media queries and other selectors, to be returned.

render()
Finally, the render-method (line 26) renders all the styles into a valid DOM node. It also keeps track of changes and automatically updates the node in the most performant way possible.

That’s it. Of course, there are many more features and details, but I wont repeat them here as well. Furthermore, if you’re interested, I invite you to read the full documention which provides much more background information and implementation details. One thing worth mentioning is the highly extendable plugin-system which adds vendor prefixing, fallback values, extending or even style validation as well as much more.

Oh, and of course, it supports universal rendering aka server-side rendering by extracting all static styles.

I hope you enjoyed reading and perhaps changed how you think about styling as part of modern web applications. I would love to get some feedback as well :)

Thanks for reading,
Robin

PS: Fela is also available for React Native and only has 2.5kb gzipped in total.

Frontend Architect. Freelancer. Creating Fela. Studying Psychology & CS. Musician. Runner. All about Functional UI. CSS (in JS), JavaScript, ReasonML.

Frontend Architect. Freelancer. Creating Fela. Studying Psychology & CS. Musician. Runner. All about Functional UI. CSS (in JS), JavaScript, ReasonML.