After comparing popular solutions such as plain CSS, Emotion, SCSS and Styled Components, I finally selected the last one. Everything seemed to be fine. It has a very popular library nowadays, which means there’s already a big community so if I’d face any problems, I’ll find probably a solution somewhere on Stack Overflow or GitHub. Besides that, Styled Components have some optimization features which means they render only when they’re needed. The project was expected to be built using React and Typescript. This library has great support for both technologies. Sounds awesome, right?
I started coding then. After a month, when the app has grown, the frontend team and me focused on delivering features, we found out that the amazing Styled Components library had its own goal and I’ll tell you why.
First of all, the naming convention. To differentiate Styled Components from React
components, I had to use the
Styled prefix which decreased code readability. Then (what
might be strange), Typescript support. Styled Components, as you might know, are based
on the CSS-in-JS approach. This means you can pass any prop to them and change the
style of, i.e., the input based on this prop and I personally think this feature is awesome. In
Typescript, you should also implement the type of this prop makes it code longer any Styled
Component. “But it would take like 5 more seconds so what is your problem” – you might
say. You’re right, although when the app scales up fast and the number of components is
increasing, these 5 seconds can be easily multiplied by hundreds of times. Another problem
is the placement of the Styled Components.
Some JS developers place them in the same file with the component they belong to, and others create separate files for them. Both approaches are good for many reasons. It mostly depends on the complexity of the component. Following one of these techniques can maintain cohesion but merging them gives exactly the opposite. We resigned from the CSS-in-JS approach and migrated to SCSS. It wasn’t easy and quick but with a little help we made it. We started styling html tags in the BEM methodology and, of course, put styles in separate files, one per component. I said that passing JS props to Styled Components is an awesome feature, but in SCSS it’s impossible. I think we also all agree that the syntax React wants to code conditional classes is awful.
Well, there’s one quite interesting solution. If you connect the BEM methodology with the
clsx library, you’ll get something like this (big shoutout to my friend Przemek Adamczyk for
showing me this library)
Looks much cleaner, don’t you think?
What’s best is that you only have to type the condition variable on the component level and not on the styling level. It really saves time. Unfortunately, such a solution has its cons. SCSS is easy and friendly but be careful when using it with Next.js. This framework doesn’t allow to import style files directly into the component file (only CSS Modules).
If you prefer
one file per component, you have to create
index.scss containing all your SCSS files and
import it into the
_app.tsx file. The only problem is that you have to manually import each
SCSS file you created. In React, though, this problem doesn’t exist and you can import SCSS
files wherever you want.
Don’t get me wrong. Styled Components are really good. As I said before, passing JS
variables as well as the global theme are amazing features. When you build a big app where
optimization is crucial, this library will probably fulfill your needs. In our case though,
migration to SCSS hit the jackpot.