Tailwind CSS takes a radically different approach to styling. Instead of writing custom CSS classes like .card-title or .btn-primary, you compose designs directly in your markup using small, single-purpose utility classes.
Why Utility-First?
Traditional CSS encourages you to create abstractions early. You name things, group styles into classes, and hope the names stay relevant as designs evolve. In practice, this leads to bloated stylesheets full of dead or duplicated CSS.
With utility-first CSS:
- No naming fatigue — you never agonize over class names.
- No dead CSS — utilities are only included if used.
- Local reasoning — you see exactly what an element looks like by reading its classes.
- Safe changes — editing one element never accidentally breaks another.
Common Utility Classes
Here is a practical example that uses many of the most common utilities:
<div class="max-w-md mx-auto bg-white rounded-lg shadow-md p-6">
<h2 class="text-xl font-bold text-gray-900">Project Update</h2>
<p class="mt-2 text-sm text-gray-600 leading-relaxed">
The new dashboard is ready for review. We shipped three
new chart components and improved load time by 40%.
</p>
<button class="mt-4 px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded hover:bg-blue-700">
View Details
</button>
</div>Breaking this down:
| Utility | What it does |
|---|---|
max-w-md | Sets max-width: 28rem |
mx-auto | Centers horizontally via margin-left/right: auto |
rounded-lg | Applies border-radius: 0.5rem |
shadow-md | Adds a medium box shadow |
p-6 | Adds padding: 1.5rem on all sides |
text-xl | Sets font-size: 1.25rem |
font-bold | Sets font-weight: 700 |
leading-relaxed | Sets line-height: 1.625 |
Responsive Prefixes
Tailwind uses a mobile-first breakpoint system. Unprefixed utilities apply at all screen sizes; prefixed utilities apply at that breakpoint and above.
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="bg-white p-4 rounded shadow">Card 1</div>
<div class="bg-white p-4 rounded shadow">Card 2</div>
<div class="bg-white p-4 rounded shadow">Card 3</div>
</div>Default breakpoints:
| Prefix | Min-width | Typical device |
|---|---|---|
sm: | 640px | Large phones |
md: | 768px | Tablets |
lg: | 1024px | Laptops |
xl: | 1280px | Desktops |
2xl: | 1536px | Large screens |
You can also use max-* variants for max-width breakpoints:
<p class="max-md:text-center md:text-left">
Centered on small screens, left-aligned on medium and up.
</p>State Variants
Tailwind provides variants for every interactive and structural state:
<!-- Hover and focus states -->
<input
class="border border-gray-300 rounded px-3 py-2
hover:border-gray-400
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
type="text"
placeholder="Enter your email"
/>
<!-- Group hover: style children when a parent is hovered -->
<a href="#" class="group flex items-center gap-3 p-3 rounded-lg hover:bg-gray-100">
<img class="w-10 h-10 rounded-full" src="/avatar.jpg" alt="" />
<div>
<p class="font-medium group-hover:text-blue-600">Jane Doe</p>
<p class="text-sm text-gray-500">Engineer</p>
</div>
</a>
<!-- First-child and odd/even -->
<ul class="divide-y divide-gray-200">
<li class="py-3 first:pt-0 last:pb-0">Item</li>
</ul>Common state variants include hover:, focus:, active:, disabled:, first:, last:, odd:, even:, group-hover:, and peer-*:.
Combining Variants
Variants can be stacked. They read left to right — "on medium screens, when hovered":
<button class="bg-blue-600 md:hover:bg-blue-800 text-white px-4 py-2 rounded">
Save
</button>Arbitrary Values
When Tailwind's default scale does not have the exact value you need, use square brackets:
<div class="top-[117px] bg-[#1a1a2e] text-[clamp(1rem,2.5vw,2rem)]">
Custom values
</div>This keeps you in the utility workflow without dropping into a CSS file.