Use Tailwind when…
A designer or design-minded dev is crafting a distinctive, branded product by hand and wants pixel-level control.
Not a takedown - Tailwind is excellent for humans who want control. This is about what happens when a model writes your UI.
<div class="max-w-sm rounded-xl border border-gray-200
bg-gray-50 shadow-sm overflow-hidden">
<div class="px-6 py-4 border-b border-gray-200 font-medium">
Pro plan
</div>
<div class="p-6">
<p class="text-gray-500">Everything in Free, plus…</p>
</div>
<div class="px-6 py-4 border-t border-gray-200 bg-gray-100
flex items-center gap-2">
<button class="inline-flex items-center justify-center
rounded-lg bg-gray-900 px-4 py-2 font-medium text-white
hover:bg-gray-800 transition-colors">
Upgrade
</button>
</div>
</div>Every value is a decision: gray-50 or gray-100? rounded-lg or xl? px-6 or p-6? Each is valid - so each generation chooses differently.
<!-- HTML -->
<article class="card">
<div class="card-header">Pro plan</div>
<div class="card-body">
<p class="muted">Everything in Free, plus…</p>
</div>
<div class="card-footer">
<button class="btn btn-primary">Upgrade</button>
</div>
</article>
/* CSS - written, named and maintained by you */
.card { border: 1px solid #e5e7eb; border-radius: 12px;
background: #f9fafb; box-shadow: 0 1px 2px rgb(0 0 0 / .05);
overflow: hidden; }
.card-header { padding: 16px 24px; border-bottom: 1px solid #e5e7eb;
font-weight: 500; }
.card-body { padding: 24px; }
.card-footer { padding: 16px 24px; border-top: 1px solid #e5e7eb;
background: #f3f4f6; display: flex; gap: 8px; }
.muted { color: #6b7280; }
.btn { /* …and 15 more lines for states */ }Total control, total responsibility: you invent the class names, write every state, and keep it consistent across the codebase yourself.
<article data-component="card">
<div data-slot="header">Pro plan</div>
<div data-slot="body">
<p data-tone="subtle">Everything in Free, plus…</p>
</div>
<div data-slot="footer">
<button data-component="button">Upgrade</button>
</div>
</article>One canonical form. Ask five times, get the same markup five times - and canon-lint proves it mechanically.
| Tailwind v4 | Vanilla CSS | Canon | |
|---|---|---|---|
| Valid ways to write this card | Hundreds | Unlimited | One |
| Same output across LLM generations | Varies per run | Varies per run | Consistent |
| Mechanical validation | - | - | npx canon-lint |
| Build step | Yes | No | No |
| CSS shipped | ~10kb (purged, varies) | Grows with the project | 3.8kb gzip, fixed |
| Prompt cost to teach an LLM | Trained-in, but unconstrained | N/A | ~600 tokens |
| Design freedom | Very high | Total | Deliberately low |