Skip to content
Sahil Durgia/ full-stack
2 min readCSS & Tailwind

Why Utility-First CSS Won: Tailwind CSS From First Principles

Not 'it's popular' — the specific problem Tailwind solves that hand-written CSS classes structurally can't, once a codebase and team grow large.

Tailwind CSSCSS architectureutility-first

The instinctive objection to Tailwind is almost always the same: "isn't this just inline styles with extra steps?" It's a reasonable first reaction, and it misses the actual structural problem Tailwind is solving — one that has nothing to do with how the class names look.

The real problem: CSS has no natural scope

A hand-written class, `.card`, is global by default — write `.card { padding: 16px; }` anywhere in a large codebase, and it silently affects every element with `class="card"` anywhere else too, including ones written by someone else, in a different file, for a different purpose. As a codebase and a team both grow, this produces a real, specific failure mode: nobody can safely delete or edit a CSS rule, because nobody can be fully sure what else depends on it. The CSS specificity post in this series covers the resulting symptom (specificity wars); this is the actual root cause underneath it.

What utility classes structurally fix

<div class="rounded-xl border border-neutral-800 p-6">
  <!-- p-6 here can never leak out and affect a DIFFERENT card elsewhere,
       because there's no shared, named .card class for two components
       to accidentally collide on -->
</div>

Each utility class does exactly one, small, predictable thing, and there's no custom class name to accidentally collide with someone else's. Deleting a component's markup deletes its styling completely — there's no orphaned `.card` rule left behind in a stylesheet, quietly unused or, worse, quietly still affecting some other element that also happened to use that class name.

The actual cost, honestly

Markup gets visually noisier — a real, genuine tradeoff, not a myth. And consistency now depends on a shared token system (this site's own `@theme` block of design tokens in `globals.css` is that system) rather than a hand-maintained style-guide document — which is a net win only if that token system is actually kept disciplined. Tailwind doesn't remove the need for design discipline; it moves where that discipline has to live, from scattered CSS files into one central configuration that's much harder to silently drift out of sync.

Keep reading
Next: Tailwind vs plain CSS vs CSS-in-JS

Part 7 of the CSS and Tailwind series.