> The only options here that are actually CSS are variables (which are relatively new to the language) and utility classes
So before widespread adoption of SASS/LESS, I might have expected some places that took a systematic approach to design to use utility classes as kind of a mid-tier in a three-layer model that took care of balancing general, cross-cutting, and specific concerns:
- general (or very widely cross-cutting) concerns would go at high levels: *, html, body, sometimes qualified with semantic classes for varying pages (e.g. body.departmentname, html.sitesection). A lot of type/line related information would go here, probably some page level margin/padding/alignment and a few other instructions. Then there'd be some kind of generalizations for other tag-level elements (ul, p, table, h1-6, etc).
- modestly cross-cutting concerns would get their own utility class names, roughly grouped by categories you're talking about (spacing, position, size, typography, color, decoration, etc), so you'd see .box-I, .type-IV, .col-X, .scheme-C
- specific/exceptional "last mile" scoped concerns would get semantic class names (also usually used for attaching behavior via JS).
The rise of SASS/LESS seemed to change one major thing: a lot of the middle/modest layer of cross-cutting concerns could/would find their way into mixins and then get imported into semantic class names, keeping the concerns centralized while cutting down on utility class name clutter in the markup. Some shops would use variables instead. Either way, it streamlined the already existing manner of handling the middle layer of cross-cutting concerns.
Now, mixins/@apply aren't part of native CSS yet (and though variables are, they're are probably inferior from a DRY/structural perspective), but existing preprocessors have had such widespread adoption for most of the last decade that it's confusing to me for someone to approach Tailwind as if isolating cross-cutting concerns weren't a problem solved in other ways previously. Certainly Tailwind's @apply isn't native either and I'm not clear on why its utility classes would be inherently superior to other pre-existing utility practices.
Hence my assumption that most of Tailwind's fans are people who hadn't found themselves working with these concepts before they picked it up. And if Tailwind is people's introduction to working that way -- and it was that hard to come by beforehand -- maybe if nothing else it is in fact doing people that favor, albeit with the overhead of being married to a level of utility classes that I think is simultaneously too scattered and duplicative and its own specific tooling.
Or maybe there's something else I don't understand about it yet?