Tailwind CSS is a utility-first CSS framework that allows you to build modern websites without ever leaving your HTML. Unlike traditional frameworks like Bootstrap or Foundation, Tailwind doesn't provide pre-designed components. Instead, it gives you low-level utility classes that let you build completely custom designs.
There are several ways to install Tailwind CSS:
Option 1: Using npm
npm install -D tailwindcss
npx tailwindcss init
Option 2: Using CDN (not recommended for production)
<script src="https://cdn.tailwindcss.com"></script>
Create a tailwind.config.js file:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{html,js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Create a CSS file that includes Tailwind's directives:
/* src/input.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Process your CSS with Tailwind CLI:
npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch
Link the output CSS file in your HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/dist/output.css" rel="stylesheet">
</head>
<body>
<h1 class="text-3xl font-bold text-blue-500">
Hello world!
</h1>
</body>
</html>
Tailwind's approach involves using small, single-purpose utility classes to build complex components:
<!-- Traditional CSS approach -->
<div class="chat-notification">
<div class="chat-notification-logo-wrapper">
<img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div class="chat-notification-content">
<h4 class="chat-notification-title">ChitChat</h4>
<p class="chat-notification-message">You have a new message!</p>
</div>
</div>
<!-- Tailwind CSS approach -->
<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4">
<div class="shrink-0">
<img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div>
<div class="text-xl font-medium text-black">ChitChat</div>
<p class="text-gray-500">You have a new message!</p>
</div>
</div>
Tailwind uses a predictable naming pattern:
{property}-{value} for most utilities{property}-{modifier}-{value} for variants{breakpoint}:{property}-{value} for responsive utilitiesExamples:
text-center: Centers textbg-blue-500: Sets background color to blue (500 intensity)hover:underline: Applies underline on hovermd:flex: Applies flex display at medium screen size and aboveControl text appearance with utilities for font family, size, weight, color, and more:
<p class="font-sans text-lg font-medium text-gray-800 leading-relaxed tracking-wide">
Beautifully styled text with Tailwind CSS
</p>
Key typography classes:
font-sans, font-serif, font-monotext-xs, text-sm, text-base, text-lg, text-xl, text-2xl...font-thin, font-light, font-normal, font-medium, font-bold...text-{color}-{shade} (e.g., text-blue-500)text-left, text-center, text-right, text-justifyleading-none, leading-tight, leading-normal, leading-relaxed...tracking-tighter, tracking-tight, tracking-normal, tracking-wide...underline, line-through, no-underlineuppercase, lowercase, capitalize, normal-caseTailwind provides a comprehensive color palette. Below is a table showcasing the default colors with their shades and actual color display.
| Color Name | Shade | Example |
|---|---|---|
| Gray | 50 | #f9fafb |
| Gray | 100 | #f3f4f6 |
| Gray | 200 | #e5e7eb |
| Blue | 500 | #3b82f6 |
| Red | 500 | #ef4444 |
| Green | 500 | #10b981 |
For the full palette, refer to the Tailwind CSS Color Documentation.
Tailwind provides a range of font sizes. Below is a table with examples:
| Class | Font Size | Example Text |
|---|---|---|
text-xs |
0.75rem | Extra Small Text |
text-sm |
0.875rem | Small Text |
text-base |
1rem | Base Text |
text-lg |
1.125rem | Large Text |
text-xl |
1.25rem | Extra Large Text |
text-2xl |
1.5rem | 2XL Text |
text-3xl |
1.875rem | 3XL Text |
Tailwind's spacing utilities control padding, margin, and gap. Below is a table with examples:
| Class | Value | Example |
|---|---|---|
p-0 |
0px | Padding: 0px |
p-4 |
1rem | Padding: 1rem |
m-2 |
0.5rem | Margin: 0.5rem |
gap-6 |
1.5rem | Gap: 1.5rem |
Tailwind's responsive utilities allow you to apply styles at specific breakpoints. Below are examples:
| Breakpoint | Prefix | Min Width |
|---|---|---|
sm |
sm: |
640px |
md |
md: |
768px |
lg |
lg: |
1024px |
xl |
xl: |
1280px |
Example:
<div class="text-base sm:text-lg md:text-xl lg:text-2xl xl:text-3xl">
Responsive Text
</div>
Tailwind provides built-in support for dark mode:
<div class="bg-white dark:bg-gray-800 text-gray-900 dark:text-white">
This element changes colors in dark mode
</div>
Enable dark mode in your config:
// tailwind.config.js
module.exports = {
darkMode: 'media', // or 'class'
// ...
}
Options:
'media': Uses the operating system preference via @media (prefers-color-scheme: dark)'class': Manually toggle by adding the dark class to the html elementprimary, secondary) rather than specific colorsTailwind is designed to be customized to match your design system.
Modify the tailwind.config.js file to customize:
module.exports = {
content: [
'./src/**/*.{html,js,jsx,ts,tsx}',
],
theme: {
colors: {
primary: '#FF6363',
secondary: '#6B7280',
// ...
},
extend: {
spacing: {
'128': '32rem',
'144': '36rem',
},
borderRadius: {
'4xl': '2rem',
},
fontFamily: {
heading: ['Montserrat', 'sans-serif'],
body: ['Open Sans', 'sans-serif'],
},
},
},
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
],
}
extend adds to the default themeextend) replaces the defaultsCreate custom utilities using the @layer directive:
@layer utilities {
.text-shadow {
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.clip-path-triangle {
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
}
Create custom variants with plugins:
// tailwind.config.js
const plugin = require('tailwindcss/plugin')
module.exports = {
// ...
plugins: [
plugin(function({ addVariant }) {
addVariant('optional', '&:optional')
addVariant('group-optional', ':merge(.group):optional &')
})
],
}
@tailwindcss/forms: Better form styles@tailwindcss/typography: Rich text formatting@tailwindcss/aspect-ratio: Aspect ratio utilities@tailwindcss/line-clamp: Text truncation utilitiesWhile Tailwind is utility-first, there are several ways to create reusable components.
Extract repeated utility patterns with the @apply directive:
@layer components {
.btn-primary {
@apply py-2 px-4 bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75;
}
}
For frameworks like React, Vue, or Angular, create component abstractions:
// React component example
function Button({ type = 'primary', children }) {
const styles = {
primary: 'py-2 px-4 bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700',
secondary: 'py-2 px-4 bg-gray-200 text-gray-800 font-semibold rounded-lg shadow-md hover:bg-gray-300',
};
return (
<button className={styles[type]}>
{children}
</button>
);
}
Consider using existing component libraries built with Tailwind:
Common UI patterns implemented with Tailwind.
<nav class="bg-gray-800 p-4">
<div class="container mx-auto flex flex-wrap items-center justify-between">
<!-- Logo -->
<div class="flex items-center flex-shrink-0 text-white mr-6">
<span class="font-semibold text-xl tracking-tight">Logo</span>
</div>
<!-- Mobile menu button -->
<div class="block lg:hidden">
<button id="nav-toggle" class="flex items-center px-3 py-2 border rounded text-gray-200 border-gray-400 hover:text-white hover:border-white">
<svg class="fill-current h-3 w-3" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg>
</button>
</div>
<!-- Desktop menu -->
<div id="nav-content" class="w-full hidden flex-grow lg:flex lg:items-center lg:w-auto">
<div class="text-sm lg:flex-grow">
<a href="#" class="block mt-4 lg:inline-block lg:mt-0 text-gray-200 hover:text-white mr-4">
Home
</a>
<a href="#" class="block mt-4 lg:inline-block lg:mt-0 text-gray-200 hover:text-white mr-4">
Features
</a>
<a href="#" class="block mt-4 lg:inline-block lg:mt-0 text-gray-200 hover:text-white">
About
</a>
</div>
<div>
<a href="#" class="inline-block text-sm px-4 py-2 leading-none border rounded text-white border-white hover:border-transparent hover:text-gray-800 hover:bg-white mt-4 lg:mt-0">Sign Up</a>
</div>
</div>
</div>
</nav>
<div class="max-w-sm rounded overflow-hidden shadow-lg">
<img class="w-full" src="/img/card-top.jpg" alt="Card image">
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">Card Title</div>
<p class="text-gray-700 text-base">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vitae justo in purus hendrerit fermentum.
</p>
</div>
<div class="px-6 pt-4 pb-2">
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#tag1</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#tag2</span>
</div>
</div>
<div class="relative pt-16 pb-32 flex content-center items-center justify-center" style="min-height: 75vh;">
<div class="absolute top-0 w-full h-full bg-center bg-cover" style="background-image: url('https://images.unsplash.com/photo-1557804506-669a67965ba0?ixlib=rb-1.2.1&auto=format&fit=crop&w=1267&q=80');">
<span class="w-full h-full absolute opacity-75 bg-black"></span>
</div>
<div class="container relative mx-auto">
<div class="items-center flex flex-wrap">
<div class="w-full lg:w-6/12 px-4 ml-auto mr-auto text-center">
<div class="pr-12">
<h1 class="text-white font-semibold text-5xl">
Your story starts with us.
</h1>
<p class="mt-4 text-lg text-gray-300">
This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.
</p>
<a href="#" class="mt-8 inline-block px-6 py-3 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg">
Get Started
</a>
</div>
</div>
</div>
</div>
</div>
<div class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full" id="modal">
<div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
<div class="mt-3 text-center">
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100">
<svg class="h-6 w-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
</div>
<h3 class="text-lg leading-6 font-medium text-gray-900">Successful!</h3>
<div class="mt-2 px-7 py-3">
<p class="text-sm text-gray-500">
Your account has been successfully created!
</p>
</div>
<div class="items-center px-4 py-3">
<button id="close-modal" class="px-4 py-2 bg-green-500 text-white text-base font-medium rounded-md w-full shadow-sm hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-300">
OK
</button>
</div>
</div>
</div>
</div>
<div class="w-full max-w-md mx-auto">
<form class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
<div class="mb-4">
<label class="block text-gray-700 text-sm font-bold mb-2" for="username">
Username
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="username" type="text" placeholder="Username">
</div>
<div class="mb-6">
<label class="block text-gray-700 text-sm font-bold mb-2" for="password">
Password
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline" id="password" type="password" placeholder="******************">
<p class="text-red-500 text-xs italic">Please choose a password.</p>
</div>
<div class="flex items-center justify-between">
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" type="button">
Sign In
</button>
<a class="inline-block align-baseline font-bold text-sm text-blue-500 hover:text-blue-800" href="#">
Forgot Password?
</a>
</div>
</form>
</div>
Tailwind can generate large CSS files if not properly optimized. Here's how to optimize performance:
Tailwind v3.0+ automatically removes unused CSS with its built-in PurgeCSS integration. Configure the content option to include all files containing class names:
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{html,js,jsx,ts,tsx,vue}',
],
// ...
}
Tailwind v3.0+ uses JIT mode by default, which:
text-[16px], bg-[#bada55])Use a minifier like CSSNano in your build process:
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {})
}
}
For large projects, consider splitting your configuration:
// tailwind.config.js
const colors = require('./tailwind/colors')
const spacing = require('./tailwind/spacing')
const typography = require('./tailwind/typography')
module.exports = {
content: ['./src/**/*.{html,js}'],
theme: {
colors,
spacing,
extend: {
typography,
},
},
// ...
}
While Tailwind is utility-first, for maintainable code:
@apply or component frameworksFor custom components and utilities:
btn-primary, not btnPrimarycard-title instead of large-bold-textcustom-text-shadow instead of just text-shadowStructure your CSS files:
src/
├── css/
│ ├── main.css # Import directives and global styles
│ ├── components/ # Component styles using @apply
│ │ ├── buttons.css
│ │ ├── cards.css
│ │ └── forms.css
│ └── utilities/ # Custom utilities
│ ├── text.css
│ └── animations.css
focus:ring focus:ring-blue-300