The Case Against Tailwind CSS: Class Soup, Fake Design Systems, and a Lying Cascade
A developer who has shipped real projects on Tailwind CSS lays out why he stops short of recommending it for medium or large codebases, despite acknowledging its strengths: fast UI development, sensible spacing and color scales, and excellent documentation. His core objection is that Tailwind trades one set of problems for another. Utility-first styling doesn’t eliminate the coupling between markup and design—it just reverses its direction, making HTML depend on CSS instead of the reverse. That tradeoff is defensible inside component frameworks like React or Vue, where markup, logic, and style already live together, but it makes far less sense in server-rendered templates where separating structure from styling still pays off.
The rest of the critique targets consistency and clarity. Class names are unintuitive and inconsistent (items-center vs. justify-center vs. text-center; border for 1px but border-2 for 2px), forcing constant documentation lookups. The much-touted enforced design system leaks badly through arbitrary values like w-[347px] and unguarded mixing of near-identical colors, so discipline still rests on the developer, not the tool. For CSS beginners, the framework creates a false sense of mastery while pulling them away from the platform fundamentals. A side-by-side button example shows vanilla CSS with variables reading as self-documenting, whereas the Tailwind equivalent leans on @apply—a feature Tailwind’s own creator, Adam Wathan, has said ‘basically only exists to trick people’ and would drop if starting over.
The sharpest technical point concerns the cascade. In Tailwind, conflicting utility classes like text-red-500 and text-green-500 on the same element don’t resolve by the order you write them in the HTML; the winner is fixed by the order the compiler emits them in the final stylesheet. Reordering the markup changes nothing, leaving developers stuck reaching for !important or simply avoiding conflicting utilities. The markup, in other words, misrepresents which style actually applies—an architectural wrinkle that undercuts one of CSS’s most basic guarantees.
Read the full article
Continue reading at Hacker News →This is an AI-generated summary. Read the original for the full story.