Inline Styles are so 2016
Let’s start with the following tweet with which I couldn’t agree more:
It looks like there’s a war between CSS and inline styles people but it’s not true: everyone just wants to make their job better day after day. React, in particular, has always been communicated in a very strong way (either you accept it or not) and inline styles are not an exception.
Some weeks ago I shared a survey to compare how developers felt about inline styles the first the time they heard about them versus how they feel about them today, on a scale from one (hate) to five (love). To better understand it I also asked for their feeling about JSX, which is usually a technology that people hate in the beginning but, as soon as they get used to it, they start to love it.
The initial value was pretty good for both, higher than what I was expecting: 2.71 for JSX and 2.55 for inline styles. But while everyone loves JSX today (4.36), the sentiment about inline styles is still low (3.08).
I think that the main reason why developers have bad feelings about inline styles is because they approach them with the wrong mindset. If you don’t give it five minutes, you are not ready to unlearn everything and leave your comfort zone it’s very unlikely that you are going to love that technique. However, if your application is made by components and they are atomic, it’s easier to understand why colocating the styles inside them could be an interesting solution.
Obviously, if your CSS is a mess and you can’t create a Style Guide out of it, you’ll never find inline styles useful but if you are using BEM, your styles are well organised and, for example, each block corresponds to a component, you’ll easily get the point of inline styles.
Before going further into the topic, it’s important to understand the history of inline styles and answering this question: why are we talking about Inline Styles in 2016?
Everything started in November 2014 when Christopher Chedeau, one the creators of React talked about CSS in JS for the first time (in the Modern™ era) at the NationJS conference. He basically listed the problems they had with CSS at Facebook and he explained how they solved all of them with inline styles.
The following slide became the 10 commandments of the movement.
A few months later Colin Megill, the author of Radium, wrote a blog post entitled “Inline Styles Are the Future” to present his library. He went trough the features of Radium, the benefits of using inline styles and one of the most interesting ones is that if you put the styles inside your components, you can easily recompute the CSS at runtime.
The most important moment in the CSS in JS history (and my favourite one) has been when, in May 2015, Mark Dalgeish published “The End of Global CSS”. He started from a very simple point: since you could import the CSS inside your components as you did for any other dependencies with WebPack, you could scope the imported class names to a single component. A few days later the CSS Modules were born.
As a result, you can do pretty cool stuff like:
Recompute your styles at runtime is a very nice feature and it opens the door to many interesting solutions.
Unfortunately, as it always happen in Computer Science, whenever a problem is solved, new problems come and this applies to inline styles too. For example with inline styles you can’t use pseudo classes and pseudo elements, media queries, style fallbacks and animations.
If you want to override a rule you always have to use the !important keyword, which we all know is a bad practice. Inline styles also break the separation of concerns (if your concerns are the technologies).
The worst downside of inline styles, in my opinion, is that they make debugging extremely hard because your console looks like this:
First of all, it’s hard to find the element that you want to debug because we tend to search the elements by their class name and second it repeats the styles for each element which means that every single item of a list has the same style value and if you change one (with the DevTools), you change the style only for that particular item (and not for the rest of the list).
Another open problem of inline styles is related to performance: even if I couldn’t find a blogpost or a benchmark that clearly says that performance is worse, it’s easy to understand that if you render on the server-side ten thousand rows each one with a long style string, the size of the page is going to be bigger. It’s fair to say that compression algorithms can easily find those patterns and usually latency is the real problem, so having less HTTP calls could be good in some scenarios.
I was looking for real world examples and the only website I found that uses inline styles (a hybrid solution between classes and inline styles, to be honest) is Uniqlo. Neither Facebook or Instagram use inline styles in the real world so I believe that Christopher Chedeau just wanted to inspire the community to find the right solution rather than actually tell people to use them. And I guess he succeeded because the CSS in JS revolution has started.
CSS in JS
A lot of libraries have been released since then and I decided to try them all to find the right one for my projects. To be honest, I didn’t find the perfect one yet even if some of them solve the problem in a very smart way.
There is react-inline (also available as babel plugin) which lets you to colocate the styles inside your components and it provides a CLI to extract them at build time, which is good if you want to publish your CSS on a CDN for example.
Another interesting project is reactcss which brings classes to inline styles and it makes easy to activate/deactivate them, with a very nice API. Unfortunately, since they are real inline styles a lots of CSS features are missing.
A library worth mentioning is react-look, which recently reached the version 1 (beta) and it looks very promising in terms of features and extensibility.
The most popular one is Radium which basically adds the missing features of inline styles: pseudoclasses, media queries and so on. It’s a pretty mature library and they recently added the server-side rendering support.
As you can see here, putting inline styles inside components has some good effects: for example, everything becomes declarative and you can easily tell which styles are applied according to the current state. And, most important, it becomes easy to test the full state of you application both in terms of content and UI, as follows:
Jokes apart, if your application is well structured and you use the smart/dumb components pattern, you end up having the presentational components that only contain HTML and styles, which are exactly what the designers need to touch to do their fine tuning job. These are the only four rules for designers to work with inline styles:
- Keys are the camelCased version of the style names
- Values are strings
- Commas instead of semicolons
- Vendor prefixes (other than ms) begin with a capital letter
A lot of people are concerned with the fact that if you decide to use inline styles and then, for some reasons, you want to go back to stylesheets (after 14 months) there isn’t an easy way to migrate. Unfortunately that’s true, I couldn’t find any tools to help with that task. (If you are going to write one, please tell me).
Another dilemma is styling elements whose styles depend on the parent, for example:
If you think carefully about that, it’s a very bad approach because it breaks the encapsulation (and that’s one of the main problems that cascading brings to styles). However, if you really want the parent to decide how the children have to look, you can do it with inline styles as well. For example, if you have a red button which has to be bold when it’s rendered inside a sidebar you can create the button in the following way:
And let the parent inject the needed style as a prop:
As said before, that’s wrong because when developers are working on that button they don’t know all the variants that it could have, since any other element can apply additional styles to it. A good solution to avoid the problem is putting all the styles inside the component itself and let the parent specify the type of style to load as a prop.
In conclusion, I think that being a front-ender nowadays is one of best jobs in the world because we have new packages and new techniques to play with everyday. My advice is to always use the right tool for you project, no matter if it breaks the rules and no matter if it goes against what you learnt in the past ten years: leave your comfort zone and have fun!