Tailwind Setup & Core Concepts
Tailwind CSS — Utility-First Styling
Tailwind CSS flips the way most developers think about CSS. Instead of writing custom class names and then styling them in a separate stylesheet, you apply small, single-purpose utility classes directly in your HTML. The result is faster development, consistent spacing and color, and no more naming things.
How Tailwind Thinks
Traditional CSS workflow:
<!-- HTML -->
<div class="card">...</div>
/* CSS */
.card {
padding: 16px;
border-radius: 8px;
background: white;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
Tailwind workflow:
<div class="p-4 rounded-lg bg-white shadow-sm">...</div>
No CSS file needed. The class names are the styles. Once you know the naming system, you write styles at the speed you write HTML.
Installation
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
This creates tailwind.config.js and postcss.config.js. Configure which files Tailwind should scan:
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
};
Add Tailwind directives to your main CSS file:
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Import it in your entry point:
// main.jsx or main.js
import "./index.css";
That's it. Tailwind now generates only the CSS classes you actually use — nothing else ships.
The Spacing System
Tailwind uses a consistent scale where 1 unit = 4px:
| Class | Value |
|---|---|
p-1 | 4px |
p-2 | 8px |
p-4 | 16px |
p-6 | 24px |
p-8 | 32px |
p-12 | 48px |
p-16 | 64px |
This scale applies to padding (p-), margin (m-), width (w-), height (h-), gap (gap-), and more.
<!-- Padding -->
<div class="p-4"> <!-- all sides: 16px -->
<div class="px-4 py-2"> <!-- horizontal: 16px, vertical: 8px -->
<div class="pt-2 pb-4"> <!-- top: 8px, bottom: 16px -->
<!-- Margin -->
<div class="m-4"> <!-- all sides -->
<div class="mx-auto"> <!-- horizontal centering -->
<div class="mt-8 mb-4"> <!-- top/bottom -->
<!-- Gap in flex/grid -->
<div class="flex gap-4"> <!-- 16px between children -->
Typography
<!-- Font size -->
<p class="text-sm">Small (14px)</p>
<p class="text-base">Base (16px)</p>
<p class="text-lg">Large (18px)</p>
<p class="text-xl">XL (20px)</p>
<p class="text-2xl">2XL (24px)</p>
<p class="text-4xl">4XL (36px)</p>
<!-- Font weight -->
<p class="font-normal">Normal (400)</p>
<p class="font-medium">Medium (500)</p>
<p class="font-semibold">Semibold (600)</p>
<p class="font-bold">Bold (700)</p>
<!-- Text color -->
<p class="text-gray-600">Gray text</p>
<p class="text-blue-600">Blue text</p>
<p class="text-red-500">Red text</p>
<!-- Line height and letter spacing -->
<p class="leading-relaxed tracking-wide">Readable body text</p>
<h1 class="leading-tight tracking-tight">Tight headline</h1>
<!-- Alignment -->
<p class="text-center">Centered</p>
<p class="text-right">Right aligned</p>
Colors
Tailwind includes a full color palette with shades from 50 (lightest) to 950 (darkest):
<!-- Backgrounds -->
<div class="bg-white">White</div>
<div class="bg-gray-50">Almost white</div>
<div class="bg-gray-900">Dark</div>
<div class="bg-blue-600">Blue</div>
<div class="bg-emerald-500">Green</div>
<!-- Text colors -->
<p class="text-gray-900">Dark body text</p>
<p class="text-gray-500">Muted text</p>
<p class="text-blue-600">Link color</p>
<!-- Borders -->
<div class="border border-gray-200">Subtle border</div>
<div class="border-2 border-blue-500">Blue border</div>
Borders and Rounded Corners
<!-- Border width -->
<div class="border"> 1px border
<div class="border-2"> 2px border
<div class="border-4"> 4px border
<!-- Border radius -->
<div class="rounded"> 4px
<div class="rounded-md"> 6px
<div class="rounded-lg"> 8px
<div class="rounded-xl"> 12px
<div class="rounded-2xl"> 16px
<div class="rounded-full"> 9999px (circle/pill)
<!-- Combined -->
<button class="border border-gray-300 rounded-lg px-4 py-2">
Button
</button>
Width and Height
<!-- Fixed sizes -->
<div class="w-4 h-4"> 16×16px (icon size)
<div class="w-8 h-8"> 32×32px
<div class="w-16 h-16"> 64×64px
<!-- Percentage widths -->
<div class="w-full"> 100%
<div class="w-1/2"> 50%
<div class="w-1/3"> 33.33%
<div class="w-2/3"> 66.67%
<!-- Viewport units -->
<div class="w-screen h-screen"> 100vw × 100vh
<div class="min-h-screen"> min-height: 100vh
<!-- Max width containers -->
<div class="max-w-sm"> 384px
<div class="max-w-md"> 448px
<div class="max-w-lg"> 512px
<div class="max-w-xl"> 576px
<div class="max-w-2xl"> 672px
<div class="max-w-4xl"> 896px
<div class="max-w-7xl"> 1280px
Shadows and Opacity
<!-- Box shadow -->
<div class="shadow-sm"> Subtle
<div class="shadow"> Default
<div class="shadow-md"> Medium
<div class="shadow-lg"> Large
<div class="shadow-xl"> Extra large
<div class="shadow-none"> Remove shadow
<!-- Opacity -->
<div class="opacity-0"> Invisible
<div class="opacity-50"> 50% opacity
<div class="opacity-75"> 75% opacity
<div class="opacity-100"> Fully visible
<!-- Color with opacity using / syntax -->
<div class="bg-blue-500/20"> 20% opacity blue background
<div class="text-gray-900/80"> 80% opacity dark text
Display and Position
<!-- Display -->
<div class="block">
<div class="inline">
<div class="inline-block">
<div class="hidden"> display: none
<div class="flex">
<div class="grid">
<!-- Position -->
<div class="relative">
<div class="absolute top-0 right-0"> Top-right corner
<div class="fixed bottom-4 right-4"> Fixed bottom-right
<div class="sticky top-0"> Sticky header
<!-- Z-index -->
<div class="z-10">
<div class="z-50">
Pseudo-States
Tailwind applies pseudo-class styles using prefixes:
<!-- Hover -->
<button class="bg-blue-600 hover:bg-blue-700">
Darker on hover
</button>
<!-- Focus -->
<input class="border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 outline-none">
<!-- Active -->
<button class="active:scale-95 transition">
Pressed effect
</button>
<!-- Disabled -->
<button class="disabled:opacity-50 disabled:cursor-not-allowed" disabled>
Disabled
</button>
<!-- Group hover — parent's hover triggers child styles -->
<div class="group">
<div class="hidden group-hover:block">
Only visible when parent is hovered
</div>
</div>
Transitions
<button class="bg-blue-600 hover:bg-blue-700 transition-colors duration-200">
Color transition
</button>
<div class="scale-100 hover:scale-105 transition-transform duration-200 ease-out">
Scale up on hover
</div>
<!-- All properties -->
<div class="hover:shadow-lg transition duration-300">
Shadow grows on hover
</div>
A Complete Card Component
Putting it all together:
<div class="bg-white rounded-xl shadow-md overflow-hidden max-w-sm">
<img
class="w-full h-48 object-cover"
src="/course.jpg"
alt="Course cover"
/>
<div class="p-6">
<span class="text-xs font-semibold text-blue-600 uppercase tracking-wide">
React
</span>
<h2 class="mt-1 text-xl font-bold text-gray-900 leading-tight">
React for Beginners
</h2>
<p class="mt-2 text-gray-500 text-sm leading-relaxed">
Learn React from scratch. Build real projects with hooks and modern patterns.
</p>
<div class="mt-4 flex items-center justify-between">
<span class="text-2xl font-bold text-gray-900">$49</span>
<button class="bg-blue-600 hover:bg-blue-700 text-white text-sm font-semibold px-4 py-2 rounded-lg transition-colors duration-200">
Enroll Now
</button>
</div>
</div>
</div>
Customizing the Theme
Extend Tailwind's defaults without replacing them:
// tailwind.config.js
export default {
theme: {
extend: {
colors: {
brand: {
50: "#eff6ff",
500: "#3b82f6",
900: "#1e3a8a",
},
},
fontFamily: {
sans: ["Inter", "system-ui", "sans-serif"],
},
spacing: {
"18": "4.5rem",
"88": "22rem",
},
},
},
};
Now bg-brand-500, font-sans, and w-88 work just like built-in utilities.
@apply for Reusable Patterns
When a combination of utilities appears repeatedly, extract it:
/* In your CSS file */
@layer components {
.btn-primary {
@apply bg-blue-600 hover:bg-blue-700 text-white font-semibold
px-4 py-2 rounded-lg transition-colors duration-200;
}
.card {
@apply bg-white rounded-xl shadow-md overflow-hidden;
}
.form-input {
@apply w-full border border-gray-300 rounded-lg px-3 py-2
focus:border-blue-500 focus:ring-2 focus:ring-blue-200
outline-none transition;
}
}
Use sparingly — the point of Tailwind is avoiding custom class abstractions. Reserve @apply for base component styles that appear in dozens of places.
Next lesson: Building UI components with Tailwind — navigation, cards, forms, and modals.
Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises