"Tailwind isn't a different language. It's CSS shorthand with a standardized vocabulary."
What Tailwind Actually Is
Tailwind is a CSS framework that ships thousands of single-purpose utility classes — .flex, .gap-4, .text-amber-500, .rounded-lg, .shadow-md. Each class sets one CSS property. The framework's value isn't the classes themselves; it's that they're standardized, design-tokened, and composable.
Instead of writing .card { display: flex; gap: 1rem; align-items: center; padding: 1rem; } in a stylesheet, you write <div class="flex gap-4 items-center p-4"> in the HTML. Same result; different authorship pattern.
Why Tailwind Works (Now That You Know CSS)
Three things make Tailwind viable:
- Every utility is single-class specificity (0,0,1,0). No specificity wars. Source order in the emitted CSS determines order; Tailwind controls it deterministically.
- It uses cascade layers internally (
@layer base, components, utilities). Utilities are always in the latest layer, so they reliably win over your own component CSS — unless you put your component CSS in a later layer too. - The utilities encode a design system.
p-4is always1remof padding (the project's design token), not a random value.text-amber-500is the canonical amber. Consistency by composition.
Reading Tailwind As CSS
Knowing CSS makes Tailwind instantly readable. A few common patterns:
flex items-center gap-4 p-6 rounded-lg shadow-md bg-white=display: flex; align-items: center; gap: 1rem; padding: 1.5rem; border-radius: 0.5rem; box-shadow: ...; background: white;md:flex-row md:gap-8= at the medium breakpoint (768px+), switch to row direction and 2rem gap.hover:bg-blue-500 focus-visible:ring-2= hover state changes background; focused state shows a ring.dark:bg-gray-900 dark:text-gray-100= when the user prefers dark mode, swap background and text.grid grid-cols-1 lg:grid-cols-3 gap-4= single column by default; 3 columns on large screens.
When Tailwind Is The Right Tool
- You're building a UI with many small components (a SaaS app, a dashboard, a marketing site).
- You want a design system that's enforced at the class-name level (no random padding values).
- You want to skip the file-context switch (CSS in one file, markup in another) — colocate everything in the JSX/HTML.
- You want predictable specificity and a stable mental model for cascade.
When Raw CSS Is Better
- Complex animations or keyframes (Tailwind covers basic ones; bespoke is easier in CSS).
- Content-specific styling (article typography with custom
::first-letter, drop caps, etc.). - Generated content via
::before/::afterwith computed values. - Component libraries that need their own internal styling without leaking utility classes to consumers.
- When the team finds class-list-heavy markup hard to read — that's a real preference, and CSS is a perfectly fine answer.
Custom Tokens And Plugins
Tailwind's tailwind.config.js lets you extend or replace the default tokens. Custom colors, spacing scales, font families, shadows. Plugins add new utilities (custom animations, scrollbar styles). When you need a class that doesn't exist, you can:
- Use
@applyin a CSS file to bundle multiple utilities under a component name. - Write raw CSS in a
@layer componentsblock — it composes correctly with Tailwind's layer order. - Use arbitrary values inline:
w-[547px]for a one-off width.
Pippa's Note
flex items-center gap-2 px-4 py-2 rounded-md bg-accent hover:bg-accent-strong. Every card is p-6 rounded-lg shadow-md bg-card. The design tokens (accent, card, etc.) live in tailwind.config.js. The vault-loaded Pippa identity reads as CSS classes for the chat bubbles. When a Tailwind utility doesn't cover what we need — an avatar-emotion fade animation, a council-card flip — that lesson lives in a small handwritten CSS file inside @layer components. Both worlds, side by side.