Adán Carrasco
Posted on April 6, 2020
An interesting topic when doing Web Development and nowadays not only Web Development is choosing how your Application will be styled. In today's post I will be comparing some of the pros and cons in CSS as well as in CSS in JS.
What is CSS?
Cascading Style Sheets, is a technique to change the look and feel of your Web App, you do it using selectors (what rules you want your styled to be applied to), selectors can be via created HTML tags, ids, CSS classes, etc; once you have your selector you can set different props, as font color, background color, font family, etc.
One of the main advantages of CSS is that you can change the look and feel of many elements at once with a selector.
/* This rule will set the font-size and font-color
as 12 pixels and orange to all the paragraphs in our whole application */
p {
font-size: 12px;
color: orange;
}
Now, what is CSS in JS?
Is nothing more that applying styling to your Components using CSS props via JavaScript, how this is possible? There are many ways, one it's adding inline styles (props) to your component.
// This will render a component (build with React) with the same
// props as we defined in the previous code
const MyComponent = props => (
<p style={{fontSize: '12px', color: 'orange'}}>hello</p>
)
Another way to do it is using a library as EmotionJS that will generate some CSS classes for you and will inject them into your Components.
// This will render a Styled Component with the same props
// as the two previous examples
const MyComponent = props => (
<MyStyledP {...props}>hello</MyStyledP>
)
const MyStyledP = styled.div`
font-size: 12px;
color: orange;
`
One of the main advantages of CSS in JS is that you have only the CSS your component needs, preventing any overrides and making it usable as a standalone piece of code.
CSS
Pros
The standard to change the look and feel in Web Development
In the old days was really hard to keep the same color for different components and was really easy to have a lot of duplicated CSS (when multiple developers were working in the same project). This was because there was no variables to persist non changing values and there was no easy way to reuse rules. Then it became the standard with the war of different browsers as Internet Explorer, Mozilla and then Chrome.
Can use preprocessors
Later preprocessors as LESS and SASS came to make the use of variables and reusing code possible, you could easily nest your inner selectors being wrapped by the main CSS class and also add some variables to it.
Good performance
Since it's and became the standard it's really easy for Web browsers to apply the styles, they have been doing it all the time. Also, the output code applied to the HTML elements is only the needed even tough the CSS code can contain non needed and non used code.
Applying a CSS theme/skin is easy
If you follow a good naming for your selectors and the use of namespacing, will be really easy to come with a different theme and apply it to your Web App.
Cons
Naming is hard, unless you follow BEM or similar
As CSS became the standard, patterns to apply a good CSS styling became popular, one of those is BEM (Blocks, Elements and Modifiers), following this out class name generated will be something like:
/* block--element-modifier */
.button--state-success {
/* here you put your css rules */
}
Easily to commit typos and override props, which leads to use !important in some cases
There's a high possibility that as developers we will have typos in our code, and there's a high possibility that someone will redefine an existing CSS class, and the one at the end will be the winner, unless someone uses !important
which is really nasty.
Dead code risk (dead rules) and hard to maintain
If in the Dev Team there's not strict rule on removing unused code more and more CSS will be created, and depending on the way you use to create more CSS files the harder will be to detect where you need to cut/remove the unused code, this also makes it hard to maintain
Need to worry about compatibility with browser's CSS extensions
If you are managing CSS manually you need to worry about different CSS extensions as: -moz, -webkit, -ms
CSS in JS
Pros
Uses CSS which is the standard
So you don't need to learn anything new to style your components since you've been using CSS all the time.
No need to worry about naming or overriding of props
You don't need to worry about overrides because the CSS used in your component lives in your component only.
Using frameworks as EmotionJS generates browser specific extensions as -webkit, -moz, etc
When using pure CSS you need to worry about the specific browser extensions, however when using this pattern, the library does that for you, generating any of them, this is a relief because you know that as long as the library is supported by the browser, the rules will be available.
Easy to maintain
As the CSS is in the component only it's easy to remove the CSS you no longer need. Also if your component needs some specifics you can modify those specifics depending on the use case passing the variants as props. And the best, if the component is no longer needed you only remove it and that's it. NO SIDE EFFECTS!
Cons
Performance may be affected because of the computation to inject the CSS
Since every component has its own CSS rules the JS bundle can easily grow, and in the other hand the JS needs to be processed by the browser to apply the CSS while in the other hand (using CSS only) the CSS is ready almost at the same time as the HTML components.
Hard to reuse rules
The rules applied to your components are only living in your components, this makes it really hard to reuse the rules you apply to your component to other components. However, if you are using this pattern, doesn't necessarily mean that you cannot use CSS, so mixing both approaches can solve this issue. :checkmark:
Applying some themes, skins may be more complicated but can be generated from a JSON which could be as
Applying themes when using this technique at some point could be harder compared to using CSS only, however if you have a good architecture and a good definition on how you want to use your CSS in JS you can easily spread the props from the parent component to the most inner component. Plus you can use some of the CSS variables advantages. 😉
Is it still CSS? Cascading is lost
IMO the most important paint point is that Cascading is lost and this means you cannot have a CSS in JS that will apply to a nested component, well you can, but you will be violating the principle of this technique which is independence in your components. This loss makes a lot of noise when deciding wether to use or not this technique.
Conclusion
As a personal conclusion I don't think there's a best option, it will depend in your project needs. However, nowadays I'm combining the two approaches making one stronger when the other is weak. I can use CSS variables and apply it to my Components and isolate in the Components what needs to be isolated, just as I would do it using namespacing.
When would you use one or the other?
Thanks for reading!
Posted on April 6, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
September 30, 2024