I’m not here to raise protection that protects CSS utility frames. I don’t even like the approach, myself, and nothing is above fair criticism. But fair is the keyword there. I can’t tell you how many times I’ve seen auxiliary styles compared to internal styles. Sarah Dayan is tired of it:
[…] despite numerous attempts to dispel common misconceptions, utility-driven enthusiasts must constantly respond to an astonishing number of misconceptions. And by far, the most tired, overused Klise is that the utility classes are just internal styles.
I think this comparison makes it clear:
<div style="color: #3ea8ca;"></div> <div class="color-blue"></div>
The first div has
color is placed directly in the HTML code, which is a very accurate value for the color blue. The other has
color set outside of HTML, using the class name allows you to specify a blue tint in CSS. Sure, the other is a rather limited class name in that, as the name suggests, does one job, but it still offers some abstractity that the blue color can be changed without changing the notation. It is said that the same story is with the utility class of the size class
size-xl. It is also an abstraction that we can use to specify the fill of an element in CSS using the name of that class as a selector. But if we wanted to use
style="padding: 10px;" directly to the HTML element, which is an absolute value that requires changing the value in the tag.
However, to be fair (what we want), there are quite a few classes in utility frames that are named so that they are very close, like inline styles. For example,
top-0 Tailwind means
top: 0 and there is no composition or abstraction from it. It is not that the class is updated in CSS with any value other than zero because it is in the name. “Utility” is a good way to describe it. It is very similar to the inline style.
All of these configurable and smart defaults put utility-based frames in a different category. Internal styles do not include any restrictions on how you format things (other than hard restrictions such as no virtual selectors or media polls), while a limited set of auxiliary categories offers quite a few style restrictions. These restrictions are common desirable in that they lead to a design that looks consistent and comfortable instead of inconsistent and careless.
To quote a metaphor I once heard in another context: Utility class frames are like bumper bowling for design. Use classes and it will work well. You may not get a strike, but you may not get a gutter ball either.
Another unfair criticism I hear in the debate on utility frameworks is that you post a lot more CSS with them. If you are, then you are definitely screwing. I think the main focus of this approach is shipping Less CSS (categories you use only). I am the first to tell you that the construction process does this accurately and perfectly is awkward and can lead to an unhealthy amount of technical debt, but I’ll surrender that if you do it right, sending less CSS is good performance. Tailwind in particular encourages and helps you do this.
So all that said, I think there is all sorts of criticism of the approach. For example, I personally don’t want to look at all of these categories. Not just. I’m not absolutely completely abstract about classes, but showing 10-20 classes in a div after a div prevents what I’m trying to do with HTML modeling. It feels harder to refract. It feels harder to see what’s happening semantically. It’s harder to structure this list into other classes that I have to do non-formative things. Some of the benefits that I would get from utilities, such as scaling styles exactly where I need them, often get through other tools.