Tailwind and styling
< BackWhen I first learned about Tailwind, I was not 100% bought in. Several years later, after working on several Tailwind projects, including a laborious Tailwind migration from v3 to v4 (it was mostly on our side though, since we had lots of SCSS that conflicted with Tailwind), I still hold my initial opinion. But if I were to start a new project, I'll probably pick Tailwind. Am I contradictory? Maybe. That's why I want to write it down.
The biggest problem with Tailwind for me is the term-remembering burden. Several years later, I still need to keep the official docs open as a reference when coding. Tailwind forces you to learn a dialect that's not part of native CSS.
CSS terms are already hard to learn. After you finally learn align-items: center, you realize that you also need to remember in the Tailwind world whether it's item-center, align-center, items-center or align-items-center. And if somehow you remember the trick by removing the first part, align-, from align-items: center -> items: center -> items-center, you'll face another pain trying to find the Tailwind term for justify-content: center. Good luck.
The other problem is on the build side. Tailwind is not a pure JS library, but something that needs to stay in your build chain. JIT makes the output much smaller, which is great, but brings complexity, and the fundamental problem: which files should we scan? I believe many people have fought for many hours trying to find the best rule to exclude the files they don't want to spend time on. Automatic content detection sounds great, but it's basically ignoring files based on a heuristic list. Theoretically it's less optimal than an curated content list, but most people won't notice because of the biggest advancement in Tailwind 4: Oxide makes the cost much easier to ignore. Still, it doesn't change the nature of Tailwind as a build-time tool. Same for the Vite plugin, but it doesn't cover all consumers, including one of the "de facto" React frameworks.
To me, as mostly a React developer, the most intuitive styling approach is the style prop. It's nearly identical to native CSS, and requires no configuration. The con is also obvious - the lack of CSS selectors. CSS Modules might be the cleanest approach since it's supported by most bundlers out of the box, but it triggers another thing I don't like - jumping between places when coding.
So, ergonomics alone, a CSS-in-JS solution might be my favorite. The experience is very close to React's style prop, with no context switching, and no need to remember the magic terms.
However, why might I still pick Tailwind for a new project? Because after years of hard times, I can now proudly say I've remembered 90% of the frequently used Tailwind classes :D. And last and most importantly: because LLMs and Tailwind are like bread and butter, Tailwind is almost like "built to save tokens", and the remembering burden for human beings is negligible compared to the big memory that runs LLMs. This forms a positive feedback loop: the more people use Tailwind, the better LLMs are at Tailwind. And I can probably assert that Tailwind will be the last language humans will learn about CSS. After that, it will be the era where AI writes code you cannot read, and thus, for sure, nothing for you to learn :)