What is the best scalable CSS approach?
First, what does scalable CSS mean? To me:
- The CSS approach works for any size project. The “scaling” part usually implies “works for large-scale projects”, but I prefer thinking of it more literally: a CSS approach that can work for a small site and remain the same approach for a large site.
- Complexity stays low. It’s not hard to jump in and see how things work. Developers don’t need very specialized knowledge. The approach can scale to any team size with varied skill levels.
- There is a plan to deal with specificity. Generally, that means keeping it low and level to avoid fights. If there is no plan and specificity values are spiky, you’ll see problematic behavior start in the form of overly complex selectors and dangerous override behavior, as with
!important
. - Consistency is high. If you are naming things, the way they are named is consistent. The order of things is consistent. The formatting is consistent. The organization is consistent.
- The approach feels productive. Developers aren’t fighting the system, they are using the system. When they sit down to work, styling is easy and natural.
- Developers don’t become afraid of the CSS. Whatever approach shakes out, everybody involved needs to understand it so that no one worries about changing it. Limit the side effects.
- It doesn’t deteriorate over time. No choices are made that become harder to make as code grows. Tiny bespoke tools are avoided in favor of robust, proven tools.
So what is that approach? I dunno — that’s for you to choose.
I will say that hand-written vanilla CSS files are a perfectly fine option. You can achieve all of this, including the scaling part, without any tooling, which buys you serious longevity. This has become more tenable with the advent of things like custom properties that wrangle consistency.
Myself, I think some tools are a good idea. But as few as possible, and the easier they are to stop using, the better. A code formatting tool like Prettier almost feels like a given for keeping things consistent. Any sort of syntax processing I’m more and more on the fence about. I actually feel stronger about using a tool that does strong scoping for your CSS, so you can attach styles to individual components without unwanted style leakage, although that may be helped along by the future @scope
rules.
There are more hurdles and trade-offs as you go. Cache busting. Bundling files for performance. Critical CSS. Linting. Browser refreshing/hot module reloading. Dynamic styles. They all have a purpose, and all introduce complexity. Choose wisely.
The recent article The evolution of scalable CSS digs into this stuff, naming actual tools through the history of this topic, in case you want examples of actual tech choices. Who runs that site, by the way? The byline is REM but it’s not the rem I know, is it?
I feel like tailwind offers all the criteria you noted here.
Try to swap out tailwind for another solution. Nearly impossible, requires massive rewrites of styles. Tailwind locks you in an creates a walled garden of abstraction. Neat approach, total fail for the open and flexible web.
Can you share more about your assumptions around 1)? I understand your general thinking, but the argument seems to fall flat fast unless there are some premises missing. For example, is that small site limited in purpose (personal or commercial)? Is there more than one person working on it? Is it a short-term or a long-term project?
In a commercial, multi-people, long-term setting, small site scalability seems to be a fair point. But if this is to apply regardless of context, team, and vision, then scalability easily can be uneconomic—and may even prevent scaling, when all the scaling work is more complex than the project itself.