We need to talk about two use-cases separately:
CSS for design systems is fine. You can define a .button[data-variant=”primary”]. It’s intuitive, performant, makes sense.
CSS for application code is terrible — specifically layout & typography. The different kinds of flex/grid layouts are tightly coupled to the dom structure. Tailwind is a great fit here:
<li class=”flex flex-col”>
<div class=”font-medium”>Title</div>
<div class=”text-sm”>Subtitle</div>
</li>
When you remove layouting concerns and maybe typography. You actually get close to the separation of concerns that CSS was initially aiming for. HTML determines arrangement and css determines the design system (colors, borders, shadows etc...).I havent seen this discussed a lot. The old Radix team had a short note: https://www.radix-ui.com/blog/themes-3#the-best-of-both-worl...
For a very long time now I've avoided anything other than 1 class per div with style overrides and written with modular rules and 1-2 degrees of separation between label and rules.
Something like
.title {
}This has the advantage of being naturally rule based and amazingly succinct to write and understand. Needless to say I'm an odd duck, since I almost never see css written this way.
(edit: I forgot how to format code on HN)