What Is Tailwind CSS? —
Setup, Installation & the Basics You Need to Know
Tailwind CSS is a utility-first framework that changes how you write styles. But it requires a build step, CDN won't cut it for production, and v4 introduced a whole new configuration model. Let's clear it all up.

What Tailwind CSS Actually Is (and Isn't)
If you've used Bootstrap, you know the drill: grab a pre-built component, drop it in, customize later. Tailwind takes a fundamentally different approach. There are no pre-built buttons or cards. Instead, you get hundreds of tiny utility classes — each one mapping to a single CSS property — and you compose your designs directly in HTML.
Think of flex, p-4, text-center, bg-blue-500. Each class does exactly one thing. You stack them together to create any design you want. It's like having a box of precisely labeled LEGO bricks instead of a pre-assembled toy.
<button class="bg-blue-600 text-white font-bold py-3 px-6 rounded-lg hover:bg-blue-700 transition-colors">
Submit
</button>
↑ Hover to see state variants in action
"Isn't that just inline styles?" — a question everyone asks once. The answer is no. Tailwind gives you responsive prefixes (md:, lg:), state variants (hover:, focus:), and a consistent design token system (spacing scale, color palette, typography scale) that inline styles simply can't provide. You get the co-location benefits of inline styles with the full power of CSS.
Installation — Node.js Is Required. CDN Is Not for Production.
Here's the thing that trips up beginners: Tailwind CSS needs a build step. It scans your HTML files, finds every class you've used, and generates a CSS file containing only those styles. That scanning and generating process requires Node.js.
Three Ways to Install (v4)
Tailwind CSS v4, released January 2025, dramatically simplified the setup process. You have three options depending on your stack.
Option 1: Vite Plugin (Recommended)
If you're using Vite (or a Vite-based framework like SvelteKit), this is the fastest and most performant option.
npm install tailwindcss @tailwindcss/vite
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [
tailwindcss(),
],
});
@import "tailwindcss";
Option 2: PostCSS Plugin (Next.js / Angular)
For frameworks that already have a PostCSS pipeline, this plugs in seamlessly.
npm install tailwindcss @tailwindcss/postcss postcss
export default {
plugins: {
"@tailwindcss/postcss": {},
}
};
Option 3: Tailwind CLI (Static HTML sites)
No bundler? No problem. The CLI watches your files and outputs compiled CSS directly.
# Install
npm install tailwindcss @tailwindcss/cli
# Create input.css with: @import "tailwindcss";
# Build & watch
npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watch
The Big v4 Change — No More tailwind.config.js
In Tailwind v3, customization lived in a JavaScript config file. Want to add a brand color? Edit tailwind.config.js. Change a breakpoint? Same file. It worked, but it meant maintaining yet another config file in your project root.
v4 flips this entirely. Customization now happens in your CSS file using the @theme directive. This is called "CSS-first configuration."
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
brand: '#1a73e8',
},
fontFamily: {
body: ['Noto Sans JP', 'sans-serif'],
},
},
},
content: ['./src/**/*.{html,js}'],
};
@import "tailwindcss";
@theme {
--color-brand: #1a73e8;
--font-body: "Noto Sans JP", sans-serif;
}
When you define --color-brand inside @theme, Tailwind automatically creates utility classes like bg-brand, text-brand, and border-brand. Define --font-body, and font-body becomes available. The naming convention is consistent and predictable.
The other major improvement: the content array is gone. v4 automatically detects your template files by scanning your project and respecting your .gitignore. In most cases, zero configuration is needed to get started.
This text uses text-brand
Core Utility Classes — The Patterns to Learn First
Tailwind has a predictable naming system. Once you internalize the pattern, you can guess class names without checking the docs. Here's the mental model.
Spacing (Margin & Padding)
In v4, spacing is calculated from a base variable: --spacing: 0.25rem. The number you put in the class is multiplied by that base. So p-4 means 0.25rem × 4 = 1rem (16px).
/* Padding */
p-4 /* all sides: 1rem */
px-6 /* horizontal (inline): 1.5rem */
py-2 /* vertical (block): 0.5rem */
pt-8 /* top only: 2rem */
/* Margin */
m-4 /* all sides: 1rem */
mx-auto /* horizontal auto (centering) */
mt-12 /* top only: 3rem */
/* Gap (Flex / Grid) */
gap-4 /* gap between items: 1rem */
gap-x-2 /* horizontal gap only: 0.5rem */
Typography
text-sm /* font-size: 0.875rem */
text-2xl /* font-size: 1.5rem */
font-bold /* font-weight: 700 */
text-center /* text-align: center */
leading-tight /* line-height: 1.25 */
tracking-wide /* letter-spacing: 0.025em */
text-gray-700 /* color: gray-700 */
Layout
flex /* display: flex */
grid /* display: grid */
hidden /* display: none */
items-center /* align-items: center */
justify-between /* justify-content: space-between */
flex-col /* flex-direction: column */
w-full /* width: 100% */
max-w-md /* max-width: 28rem */
State Variants — hover: / focus: / dark:
This is where Tailwind's power really shows. Prefix any utility with a variant, and it only applies in that state. No separate CSS file, no context-switching.
<button class="bg-blue-600 hover:bg-blue-700 focus:ring-2 focus:ring-blue-300 active:scale-95 transition">
Click me
</button>
<!-- Dark mode -->
<div class="bg-white dark:bg-gray-900 text-black dark:text-white">
Content
</div>
↑ number × 0.25rem — predictable, consistent
Putting It Together — Your First Layout
With just the classes covered above, you can build a full page layout. Here's a header + main + footer structure — the bread and butter of any site.
<body class="min-h-screen flex flex-col bg-gray-50">
<header class="bg-white shadow-sm">
<nav class="max-w-5xl mx-auto px-4 py-4 flex items-center justify-between">
<a class="text-xl font-bold text-gray-900">MySite</a>
<ul class="flex gap-6 text-sm text-gray-600">
<li><a class="hover:text-blue-600 transition-colors">About</a></li>
<li><a class="hover:text-blue-600 transition-colors">Works</a></li>
<li><a class="hover:text-blue-600 transition-colors">Contact</a></li>
</ul>
</nav>
</header>
<main class="flex-1 max-w-5xl mx-auto px-4 py-12">
<h1 class="text-3xl font-bold text-gray-900 mb-4">Welcome</h1>
<p class="text-gray-600 leading-relaxed">Your content here.</p>
</main>
<footer class="bg-gray-900 text-gray-400 text-center py-8 text-sm">
© 2025 MySite
</footer>
</body>
The key combo here is min-h-screen flex flex-col on the body, with flex-1 on main. This creates a sticky footer that stays at the bottom even when content is short — a pattern that used to require careful CSS trickery, done in three classes.
Common Questions
"Aren't the class lists way too long?"
At first, yes, they look overwhelming. But you get used to it fast, and the benefit — seeing all styles at a glance without hunting through files — outweighs the visual noise. For repeated patterns, extract them into components (in React/Vue) or use @apply sparingly in your CSS.
/* Don't do this — you're just reinventing BEM with extra steps */
.header { @apply flex items-center justify-between px-4 py-4; }
.nav-link { @apply text-sm text-gray-600 hover:text-blue-600; }
"Can I add it to an existing project?"
Absolutely. v4 uses CSS Cascade Layers internally, so its styles have controlled specificity and are less likely to clash with your existing CSS. If Tailwind's reset (Preflight) causes issues, you can import just the utilities layer without the base reset.
"Is there editor support?"
The official "Tailwind CSS IntelliSense" VS Code extension is essential. It gives you autocomplete for class names, hover previews showing the generated CSS, and linting for conflicts. Don't write Tailwind without it.
Takeaways
- Tailwind CSS is a utility-first framework — no pre-built components, just single-purpose classes you compose in HTML
- Production requires a build step (Node.js + Vite/PostCSS/CLI). The Play CDN is development-only and cannot tree-shake unused styles
- v4 replaced tailwind.config.js with CSS-first configuration using the @theme directive — all customization lives in your CSS file
- The content path array is no longer needed. v4 auto-detects files and respects your .gitignore
- Spacing follows a predictable formula: number × 0.25rem. Learn this once, and you can guess most spacing classes
- State variants (hover:, focus:, dark:) let you handle interactive and responsive styles without leaving HTML
- Install "Tailwind CSS IntelliSense" in VS Code — it's practically required for a productive workflow