November 13, 2019
There are overwhelmingly many options on how to style your app. CSS-in-JS solutions like styled-components, emotion & styled-jsx. You also have TailwindCSS, styled-systems and theme-ui. Then there’s functional CSS with libraries like tachyons. On top of that you have other less recent solutions like CSS-modules, SASS, SCSS, PostCSS, BEM convention using CSS vanilla and finally there are inline styles.
…And then you can mix those! Like fx. styled-system + styled-components, CSS modules + SASS… and so on..
And there are also some libraries that are built using other libraries! Like theme-ui is built on Emotion + Styled System + MDX + Typography.js
I love this tweet.. spot on :‘D
Vue: you can use CSS in your component.vue file!— Nat Alison (@tesseralis) October 29, 2019
React: you can use Themely, which builds on top of emotion, aphrodite, radium, styled-components, styled, styler, stylist, stylus, stiletto, stillborn, pig-sty, glamor, glamorous, glamoros, glam, Java Swing, the Necronomicon, ...
So, you go online, trying to figure out which CSS method to choose. Most often you’re not going to read a long story on how the person chose X rather than Y. Most of the online discussions are not well-founded or outdated.
All these options & lack of reliable information
make it hard to make up one’s mind.
I’ll be listing some things that’s good to take into account when choosing. Which points do you value the most? I won’t be trying to convince you of using one library over another. I’ll try not to be biased but it’s no secret that I usually opt for styled-components in my projects so throughout the article I might give more examples on SC than other libraries.
What’s the nature of your project?
→ Maintenance is often the most difficult part for teams. It has proven hard to following BEM. Maybe some solutions that offer scoping and even something helps you integrating a design system.
Do the designers on your team write the CSS?
→ CSS-in-JS may not be the best option.
→ Choose whatever makes you productive.
Setup / Support / Ecosystem
Find out if your stack works smoothly with the CSS library you have in mind.
Is the library mature or just got released? Are you willing to pioneer a little and share your solution with the world? Or do you want out of the box solution with 100% support?
Maybe you’re doing SSR - does the library offer a support for it? See if you need a plugin and whether people are happy with it. Are you using type systems like typescript or ReasonML? This could add some complexity, for example in your webpack configuration.
Some solutions fit together like “peas and carrots”, for example React & Styled-Components. SC was made with React in mind and today it only works with React and Vue.js. It even encourages “thinking in React”.
Is it easy to use themes with your library? And can you use them dynamically? Here’s a great in-depth article on theming, written by John Otander who’s done a great research on the pros & cons of each CSS tool, with regard to theming.
You might be developing something like an e-commerce app where the performance is important so the further you get from vanilla CSS, the more you should look into your performance budget. Check other websites already using the CSS tool, sometimes there’s a list of websites in docs. Are those examples as massive as your website and are you satisfied with the perf? CSS-in-JS libraries are not known to be the most performant but often the difference is so subtle that it doesn’t matter. You could also check if there’s some reliable benchmarking out there.
Dead code elimination
You could be in a situation with a team where nobody dares to delete CSS because everyone is afraid of breaking something.
When you write styled-components, the linter tells you immediately if you’re using the styles or not. Usually there are some ways to achieve the same with other technologies, like with SASS, you’d have to do some gulp or grunt config and run a script. Check in the doc or elsewhere, if there’s some plugin or a linter that could help you.
Scalability / Maintainability / Naming collisions
Conflicts between mutual classes are one of the biggest problems with vanilla CSS - not very scalable. At first BEM was a naming convention that was supposed to solve this problem but it’s a lot of bikeshedding to get the whole team to follow those rules - so that’s not very maintainable. CSS modules, CSS-in-JS and other solutions solve this pretty well by scoping the CSS.
Syntax highlighting pic.twitter.com/jqlpQCRpml— Dmitry Chestnykh (@dchest) August 27, 2014
What editor are you using and is there a syntax highlighter for the CSS solutions you have in mind? For some developers, this can be a dealbreaker. Some people have broken up with styled-jsx for exactly this reason but today the syntax highlighting support is much better as the community grew with next.js becoming more and more popular.
You probably have your own preferences for syntaxes.
- Some developers praise styled-components because they love how descriptive the names are for the styled components
<CardList> = readable.
- Others hate how the same syntax makes it less clear whether it’s just a styled html tag or if it’s a React component. (more on this in another article)
Same goes with styled-jsx which works pretty much like styled-components but the styles are included in the jsx. Either you prefer it or would rather keep the styles outside of the jsx, like SC does.
I could think of other points, some more specific cases compatibility with testing, learning curve etc. but in my opinion they don’t necessarily require a paragraph on their own.
So now you have a pretty good collection of things to keep in mind when you choose how to style your app!