Tailwind
Requires Tailwind CSS v4
Table of Contents
- Setup
- Layout (Flexbox)
- Layout (Grid)
- Spacing
- Sizing
- Typography
- Colors & Backgrounds
- Borders, Rounded Corners & Shadows
- Responsive Design
- State Modifiers (hover / focus etc.)
- Dark Mode
- Customization
1. Setup
Installation (Vite / Next.js etc.)
npm install tailwindcss @tailwindcss/vite
// vite.config.ts
import tailwindcss from '@tailwindcss/vite'
export default {
plugins: [tailwindcss()],
}
/* src/index.css */
@import "tailwindcss";
In v4, tailwind.config.js is not needed. Configure via @theme in your CSS file.
2. Layout (Flexbox)
<!-- Horizontal row, center-aligned -->
<div class="flex items-center justify-between gap-4">
<span>Left</span>
<span>Right</span>
</div>
| Class | Description |
|---|
flex | display: flex |
inline-flex | display: inline-flex |
flex-col | Column direction (flex-direction: column) |
flex-wrap | Allow wrapping |
items-start/center/end | Cross-axis alignment (align-items) |
justify-start/center/end/between/around | Main-axis alignment (justify-content) |
gap-{n} | Gap between children |
flex-1 | Fill remaining space (flex: 1 1 0%) |
shrink-0 | Prevent shrinking (flex-shrink: 0) |
3. Layout (Grid)
<!-- 3-column grid, equal width -->
<div class="grid grid-cols-3 gap-6">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
| Class | Description |
|---|
grid | display: grid |
grid-cols-{n} | n equal-width columns |
grid-cols-[auto_1fr] | Custom column definition (arbitrary value) |
col-span-{n} | Span n columns |
col-start-{n} | Start at column n |
gap-{n} | Gap between rows and columns |
place-items-center | Center both axes (place-items) |
4. Spacing
The spacing scale uses 1 = 4px by default.
| Class | Description |
|---|
p-{n} | Padding (all sides) |
px-{n} | Padding left/right |
py-{n} | Padding top/bottom |
pt/pr/pb/pl-{n} | Padding per side |
m-{n} | Margin (all sides) |
mx-auto | Horizontal centering |
my-{n} | Margin top/bottom |
mt/mr/mb/ml-{n} | Margin per side |
space-x-{n} | Horizontal gap between children |
space-y-{n} | Vertical gap between children |
<div class="px-6 py-4 mt-8 mx-auto max-w-xl">...</div>
5. Sizing
| Class | Description |
|---|
w-{n} | width (w-8 = 2rem = 32px) |
w-full | width: 100% |
w-screen | width: 100vw |
min-w-0 | min-width: 0 (allows flex children to shrink) |
max-w-{size} | max-width (max-w-xl, max-w-screen-lg, etc.) |
h-{n} | height |
h-full | height: 100% |
h-screen | height: 100vh |
size-{n} | Set width and height at once (v3.4+) |
<!-- Square icon -->
<img class="size-10 rounded-full" src="..." alt="" />
6. Typography
<h1 class="text-2xl font-bold tracking-tight text-gray-900">Heading</h1>
<p class="text-base text-gray-600 leading-relaxed">Body text</p>
| Class | Description |
|---|
text-xs/sm/base/lg/xl/2xl... | Font size |
font-light/normal/medium/semibold/bold | Font weight |
leading-tight/normal/relaxed/loose | Line height |
tracking-tight/normal/wide | Letter spacing |
text-left/center/right | Text alignment |
truncate | Truncate overflow text with ... |
line-clamp-{n} | Truncate after n lines |
whitespace-nowrap | No line wrapping |
underline | Underline |
no-underline | Remove underline |
7. Colors & Backgrounds
Tailwind colors use the format {color}-{shade} (shades range from 50 to 950).
<button class="bg-blue-600 text-white hover:bg-blue-700">
Submit
</button>
<p class="text-gray-500">Subtext</p>
| Class | Description |
|---|
text-{color}-{n} | Text color |
bg-{color}-{n} | Background color |
bg-white/black | White / black |
bg-transparent | Transparent |
bg-gradient-to-r | Gradient direction: left → right |
from-{color} | Gradient start color |
to-{color} | Gradient end color |
opacity-{n} | Element opacity (0–100) |
bg-{color}/{n} | Background opacity (e.g. bg-black/50) |
<!-- Gradient button -->
<button class="bg-gradient-to-r from-violet-500 to-purple-600 text-white px-4 py-2 rounded-lg">
Gradient
</button>
8. Borders, Rounded Corners & Shadows
<div class="border border-gray-200 rounded-xl shadow-md p-4">
Card
</div>
Borders
| Class | Description |
|---|
border | border-width: 1px |
border-{n} | Border width (border-2 = 2px) |
border-t/r/b/l | Border on one side |
border-{color}-{n} | Border color |
divide-x/y-{n} | Divider line between direct children |
Rounded Corners
| Class | Description |
|---|
rounded | border-radius: 0.25rem (4px) |
rounded-lg | 8px |
rounded-xl | 12px |
rounded-2xl | 16px |
rounded-full | Full circle (9999px) |
rounded-t/r/b/l-{size} | Per-side rounded corner |
Shadows
| Class | Description |
|---|
shadow-sm | Small shadow |
shadow | Default shadow |
shadow-md | Medium shadow |
shadow-lg | Large shadow |
shadow-xl | Extra large shadow |
shadow-none | No shadow |
9. Responsive Design
Breakpoints use a mobile-first approach (applied at the specified size and above).
| Prefix | Breakpoint |
|---|
| (none) | All sizes |
sm: | 640px+ |
md: | 768px+ |
lg: | 1024px+ |
xl: | 1280px+ |
2xl: | 1536px+ |
<!-- Mobile: column / lg and above: row -->
<div class="flex flex-col lg:flex-row gap-4">
<aside class="w-full lg:w-64">Sidebar</aside>
<main class="flex-1">Main</main>
</div>
<!-- Responsive font size -->
<h1 class="text-2xl md:text-4xl lg:text-5xl font-bold">
Heading
</h1>
<!-- Hidden on mobile / visible on md and above -->
<nav class="hidden md:flex gap-6">...</nav>
10. State Modifiers (hover / focus etc.)
<button class="bg-blue-600 text-white px-4 py-2 rounded
hover:bg-blue-700
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
active:scale-95
disabled:opacity-50 disabled:cursor-not-allowed
transition-colors duration-200">
Button
</button>
| Modifier | Description |
|---|
hover: | On hover |
focus: | On focus |
focus-visible: | On keyboard focus only (recommended) |
active: | While being clicked |
disabled: | When disabled attribute is present |
checked: | When checkbox etc. is checked |
placeholder: | Style for placeholder text |
group-hover: | When a parent with group is hovered |
peer-focus: | When a sibling with peer is focused |
group / peer Usage
<!-- Change child style when parent is hovered -->
<div class="group flex items-center gap-2 cursor-pointer">
<span>Menu</span>
<svg class="transition group-hover:translate-x-1">→</svg>
</div>
<!-- Change label style when input is focused -->
<div>
<input class="peer border rounded px-3 py-2" type="text" />
<p class="text-sm text-gray-400 peer-focus:text-blue-500">
Please enter a value
</p>
</div>
11. Dark Mode
In v4, @media (prefers-color-scheme: dark) is applied by default.
<div class="bg-white text-gray-900 dark:bg-gray-900 dark:text-gray-100">
Content
</div>
To use class-based dark mode switching, configure in CSS:
/* src/index.css */
@import "tailwindcss";
@variant dark (&:where(.dark, .dark *));
<!-- Adding .dark to the <html> tag activates dark mode -->
<html class="dark">
<body class="bg-white dark:bg-gray-900">...</body>
</html>
12. Customization
In v4, customization is done via @theme in your CSS file.
Adding / Overriding Design Tokens
/* src/index.css */
@import "tailwindcss";
@theme {
/* Custom colors */
--color-brand: #3b82f6;
--color-brand-dark: #1d4ed8;
/* Custom font size */
--font-size-hero: 4rem;
/* Custom breakpoint */
--breakpoint-xs: 480px;
/* Custom animation */
--animate-fade-in: fade-in 0.3s ease-out;
@keyframes fade-in {
from { opacity: 0; transform: translateY(-8px); }
to { opacity: 1; transform: translateY(0); }
}
}
<!-- Use custom values -->
<h1 class="text-hero text-brand">Heading</h1>
<div class="animate-fade-in">Fade in</div>
Arbitrary Values
Use [value] to specify values outside the default scale.
<!-- Arbitrary width / height -->
<div class="w-[320px] h-[calc(100vh-64px)]">...</div>
<!-- Arbitrary color -->
<p class="text-[#e84393]">Pink</p>
<!-- Arbitrary grid template -->
<div class="grid grid-cols-[1fr_2fr_1fr]">...</div>
Reuse Classes with @apply
When the same combination of classes is repeated across components.
/* src/index.css */
@layer components {
.btn-primary {
@apply bg-blue-600 text-white px-4 py-2 rounded-lg
hover:bg-blue-700 focus-visible:ring-2 focus-visible:ring-blue-500
transition-colors duration-200;
}
.card {
@apply bg-white border border-gray-200 rounded-xl shadow-sm p-6;
}
}
<button class="btn-primary">Submit</button>
<div class="card">Card</div>