We have all been conditioned and trained to decouple our styling from the DOM. Thanks to stylesheets we can separate our CSS from our HTML and all is well with the world (mostly).
But thanks to libraries like React.js, people have started using inline styling in their Javascript. For a brief moment in time I bought into the act, I drunk the Kool Aid and I was putting CSS in my React components courtesy of crowd-divider JSX.
Then I realised how much of a fool I had been. Just because React allows you to use inline styles does not mean you should. Sure, it keeps your components nice and coupled with the presentation aspect, but at what cost?
Say for example you create a component with some styling for a fancy styled radio button. You use inline styling for some aspects of it and CSS for others. You now have a CSS stylesheet with some styling and a React component with some styling in it. You have just created a mess.
Your CSS styling should not be dependent on the DOM markup, your DOM markup should be dependent on the CSS.
When you decide to use React.js inline styling you are locking yourself into using React. If you decide in a year that you need something more powerful than React or it is not meeting your needs, do you really think you will get away with just copying over your HTML/CSS and rewriting the Javascript? Not a chance.
When you use React’s JSX inline styling functionality, you’re saying, “I am never leaving you React, ever, ever, ever, ever and ever.” — you’ll spend countless hours pulling out your styling and moving it into stylesheets without a fight.
Specificity is the root of all evil
There is another side-effect that comes from drinking the inline styling Kool Aid: specificity. When you use inline styles, you can’t override them in your stylesheets.
This means if you want to override some inline styling on an element, you have to use !important
declarations or your CSS in your stylesheet will be ignored and the styling on the element itself favoured.
Because CSS is not scoped (unless you’re using the shadow DOM) people feel the need to resort to inline styling because they think it addresses the problem. Sure inline styling ensures that the styling is only being applied to this particular element, but if you can’t override it without starting World War III in your code-base, is it really worth it?
It is worth noting that there is currently an experimental feature for scoped CSS (only available in Firefox at the moment). Whether other browsers pick up this feature remains to be seen or not. I do not think scoped CSS is ever going to be picked up, Chrome had it for a brief moment of time and then removed it.
Is all inline CSS bad?
I am not saying that all inline styling is bad, this post is more aimed at those using inline styling for everything because they’re smitten with JSX or just lazy. Sometimes using inline styles just makes more sense, but I would say if I had to choose a percentage 99% of all uses are incorrect.
Performance
One of the best things inline CSS can be used for is page performance. It is a well-known practice that putting inline CSS for the first-load above-the-fold content in a page can make it render faster opposed to an external CSS stylesheet.
Using inline styling we can get the CSS to the user’s browser as soon as possible using critical CSS. Patrick Hamann a developer working over at The Guardian has a great slideshow that details using inline CSS to speed up page rendering and reduce latency.
On the other hand the downside to inline styling is it does not get cached alongside your other static assets. You shouldn’t be inlining large amounts of CSS, but if you do, it is important to know that the lack of caching will have a mild effect on page rendering performance.
The difference between inline style blocks and inline styling on an element is of course, you can override inline styling blocks without needing to use !important
as it just becomes global CSS alongside your other stylesheets.
Basic Tasks & CSS Limitations
I have used inline styling to show and hide elements. Yes, you could just create a class that hides an element, but sometimes I just use style.display='none'
to save time and not bloat my stylesheets with utility classes that serve one purpose.
I also recently needed to animate an element from height:0
to height:auto
at present this cannot be done using just CSS and transitions/animations. You need to use Javascript to read the elements height and then use that as the reference to animate.
Avoiding dead code
There is an argument that inline styling avoids dead code and you can’t deny that it is true. CSS directly coupled with a HTML element means that it is being used. It is incredibly common for most projects to have some dead CSS that has been forgotten or people are too afraid to remove. I still don’t think some added baggage from dead CSS is justification for using inline styling, but I can see how it would save a few bytes.
As you can see there are not that many situations that call for the need to use inline styling, to the point where you are probably better off just using a stylesheet and classes.
There is a point to be made here. Inline styling and inline element styling are two different things. Whereas inline styling blocks in the form of <style></style>
can be useful, inline element styling (like the type used in React) in 9.8 out of 10 use-case scenarios is a bad idea.
Conclusion
The cons far outweigh any pros when it comes to using inline styling on elements in Javascript. You lose all of the benefits you traditionally get in CSS using stylesheets like; cascading, caching, reusability and separation of concerns.
It also makes the resulting HTML easier to understand cleaner because your HTML should worry about the content and your CSS should worry about the presentation.
The allure of using CSS in your React components is strong and promising, but once you realise you’re opening up a Pandora’s Box of problems for yourself and possibly the entire team you soon realise that grandfather was right: Separation of concerns.
Keith Grant shares the same thoughts in his blog post on the subject here which I highly encourage you to read.