On this page

What is Tailwind CSS?

12 min read TextCh. 1 — Utility-first fundamentals

What is Tailwind CSS?

Tailwind CSS is a utility-first CSS framework that gives you low-level, single-purpose CSS classes — called utilities — and lets you compose them directly in your HTML to build any design without ever leaving your markup. Instead of writing .btn-primary { background: blue; padding: 8px 16px; ... } in a separate stylesheet, you write class="bg-blue-500 px-4 py-2 ..." directly on the element.

This is the core philosophy: style at the point of use. No context switching, no inventing class names, no stylesheet growing infinitely as the project scales.

The utility-first philosophy

Every CSS framework has an opinion about how to apply styles. Traditional frameworks like Bootstrap give you pre-built components: .btn, .card, .modal. You get a ready-made button quickly, but customizing it requires overriding specificity wars, and every project looks similar.

Tailwind takes the opposite approach. It gives you atomic building blocks:

  • bg-blue-500 — sets background-color to a specific shade of blue
  • text-white — sets color: white
  • px-4 — sets horizontal padding to 1rem
  • py-2 — sets vertical padding to 0.5rem
  • rounded — sets border-radius: 0.25rem
  • font-semibold — sets font-weight: 600
  • hover:bg-blue-600 — applies a darker background on hover

You compose these to build a button:

<button class="bg-blue-500 hover:bg-blue-600 text-white font-semibold px-4 py-2 rounded transition-colors">
  Click me
</button>

There are no components to override, no specificity problems. If you need a green button, you change bg-blue-500 to bg-green-500. Everything is explicit and local.

Why utility-first scales better

The paradox of traditional CSS is that it grows forever. Every new feature means new classes. Old classes are never deleted because you cannot be sure nothing uses them. After 12 months, stylesheets reach thousands of lines, and developers are afraid to change anything.

With Tailwind, your CSS file stops growing at some point. The utilities are finite — there are only so many colors, font sizes, and spacing values. Once your project uses most of them, the build output reaches a ceiling and stays there. Unused utilities are never included in the final build.

This is enabled by Tailwind's content scanning: the framework scans your HTML, JavaScript, and template files for class names and only generates CSS for the utilities you actually use. A typical production build is 5–15 KB of CSS, regardless of project size.

Tailwind v4 vs v3: what changed

Tailwind CSS v4 is a complete ground-up rewrite. The changes are significant:

The Oxide engine

Tailwind v4 replaces the pure-JavaScript PostCSS pipeline with Oxide, a hybrid engine written in Rust (using Lightning CSS) and JavaScript. Lightning CSS handles parsing, transforming, and bundling CSS at native speeds. The result is:

  • Full build times reduced by ~5× on cold builds
  • Incremental builds are near-instant — under 2ms on typical projects
  • Automatic vendor prefixes without a separate autoprefixer plugin
  • Modern CSS features like nesting, custom media queries, and color-mix() work out of the box

CSS-first configuration

In v3, configuration lived in tailwind.config.js — a JavaScript file where you defined colors, fonts, breakpoints, and plugins. In v4, the configuration moves entirely into your CSS file:

/* tailwind.css */
@import "tailwindcss";

@theme {
  --color-brand: #6366f1;
  --font-display: "Inter", sans-serif;
  --breakpoint-xs: 480px;
}

The @theme directive registers custom design tokens that generate utility classes automatically. Defining --color-brand: #6366f1 makes bg-brand, text-brand, and border-brand available immediately.

No more `tailwind.config.js`

In v4, there is no tailwind.config.js by default. The @theme block replaces theme.extend. The @source directive replaces content. The @variant directive replaces plugins for custom pseudo-class variants.

This means your entire Tailwind setup — imports, custom tokens, variant definitions — lives in one CSS file. The framework becomes a CSS library first, with JavaScript tooling as a secondary concern.

Other v4 changes

  • New color palette — the default palette was updated and all opacity utilities now use CSS color-mix() instead of CSS variables tricks.
  • P3 color support — Tailwind v4 ships with OKLCH-based colors that work in wide-gamut displays.
  • Simplified breakpoints — breakpoints are plain CSS custom properties.
  • @starting-style support — entry animations on newly inserted DOM elements.
  • Container queries built-in via @container and @min-*/@max-* utilities.

The Tailwind ecosystem

Tailwind is not just a CSS file. It comes with a rich ecosystem:

Tool Purpose
@tailwindcss/vite Vite plugin — recommended for most projects
@tailwindcss/cli Standalone CLI for non-Vite workflows
@tailwindcss/postcss PostCSS plugin for webpack, Parcel, etc.
@tailwindcss/typography The prose plugin for rich text content
@tailwindcss/forms Resets and base styles for form elements
Tailwind UI Premium component library
Headless UI Unstyled, accessible components

The VS Code extension Tailwind CSS IntelliSense (by Tailwind Labs) is essential. It provides autocomplete for every class, documentation on hover, and linting for invalid class names. Install it before writing a single line of Tailwind code.

When to use Tailwind

Tailwind is an excellent fit for:

  • Custom designs where Bootstrap or Material UI components would need heavy overriding
  • Large teams where CSS naming conventions are difficult to enforce
  • Component-based frameworks like React, Vue, Angular, and Svelte — each component owns its styles via classes
  • Design system implementations where a fixed token set maps 1:1 to utility classes

Tailwind is a poor fit for:

  • Unstyled HTML documents you do not control (e.g., user-generated content) — use the typography plugin
  • Tiny prototypes where a reset + a few custom rules are enough
  • Projects where team members strongly prefer CSS modules or BEM

Practice

  1. Open play.tailwindcss.com and recreate the card from the code example above using only utility classes. Try changing the background color and padding.
  2. Add hover:shadow-xl to the card and observe how the hover state is applied inline.
  3. Compare the generated CSS output (bottom panel) with the traditional stylesheet equivalent. Notice that only the used utilities appear in the output.

Tailwind v4 vs v3: completely different config model
Tailwind CSS v4 removes tailwind.config.js entirely. Configuration now lives inside your CSS file using @theme, @source, and @variant directives. The Oxide engine (written in Rust/Lightning CSS) replaces PostCSS as the primary build step, delivering 5–10x faster build times.
Start with the Tailwind CSS Playground
You can try every utility class from this course at play.tailwindcss.com — no installation needed. The playground runs the full Oxide engine in the browser and shows live output.
<!-- Traditional CSS approach: write classes, then style them separately -->
<style>
  .card {
    background: white;
    border-radius: 8px;
    padding: 24px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  }
  .card-title {
    font-size: 1.25rem;
    font-weight: 700;
    color: #111;
    margin-bottom: 8px;
  }
  .card-text {
    color: #555;
    line-height: 1.6;
  }
</style>

<div class="card">
  <h2 class="card-title">Hello, world</h2>
  <p class="card-text">This is a card component.</p>
</div>