TailwindCSS: elegant web design made easy
The utility-first revolution
TailwindCSS has changed the game in the CSS world. Where Bootstrap imposed pre-designed components and traditional CSS requires naming every element, Tailwind proposes a radically different approach: composing styles directly in HTML with atomic utility classes.
Result in 2025: Tailwind is the most used CSS framework for custom web development, with roughly 16% market share and massive adoption in React, Vue, and Svelte projects.
The utility-first approach explained
The problem with traditional CSS
With classic CSS, you write rules in a separate file:
/* styles.css */
.card {
padding: 1rem;
border-radius: 0.5rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
background-color: white;
}
.card-title {
font-size: 1.25rem;
font-weight: 600;
color: #1a202c;
}
Problems: class names to invent, CSS files that grow endlessly, specificity conflicts, orphan files.
The Tailwind solution
With Tailwind, style is directly in the markup:
<div class="p-4 rounded-lg shadow-md bg-white">
<h2 class="text-xl font-semibold text-gray-900">Card Title</h2>
</div>
No separate CSS file to maintain. No class names to invent. Each utility does exactly one thing and does it well.
Concrete benefits
1. Increased productivity
You never leave your template. No need to juggle between the HTML file and the CSS file. Design happens directly in the component, which significantly accelerates prototyping.
A typical 20-page marketing site generates between 6 and 12 KB of gzipped CSS with Tailwind, compared to 22 to 25 KB with Bootstrap.
2. Zero dead CSS
Tailwind v4 uses a compilation engine (based on Lightning CSS) that analyzes your source files and only generates CSS for classes actually used. In production, your CSS file contains only what you need.
3. No specificity conflicts
With utility classes, CSS specificity problems disappear. No more !important, nested selectors, or cascade hacks. The order of classes in your HTML determines the visual result.
4. Built-in design system
Tailwind enforces a consistent scale for spacing, colors, and font sizes. This consistency benefits teams:
<!-- Consistent spacing: p-1, p-2, p-3, p-4, p-6, p-8... -->
<div class="p-4 m-2 gap-3">
<!-- Theme colors: bg-primary-500, text-gray-700... -->
<button class="bg-blue-600 hover:bg-blue-700 text-white">
<!-- Responsive sizes: sm:, md:, lg: -->
<div class="w-full md:w-1/2 lg:w-1/3">
Tailwind v4: what changed
Released early 2025, version 4 is a complete rewrite with major improvements:
Build performance
| Build type | v3.4 | v4.0 | Improvement |
|---|---|---|---|
| Full build | 378ms | 100ms | 3.78x |
| Incremental rebuild (new CSS) | 44ms | 5ms | 8.8x |
| Incremental rebuild (no new CSS) | 35ms | 192µs | 182x |
The Lightning CSS engine makes builds up to 10x faster. In development, changes are reflected almost instantly.
CSS-first configuration
Goodbye tailwind.config.js! Configuration is now done directly in CSS:
@import "tailwindcss";
@theme {
--color-primary: oklch(0.7 0.15 200);
--color-secondary: oklch(0.6 0.2 280);
--font-display: "Inter", sans-serif;
--font-mono: "JetBrains Mono", monospace;
}
Variables are exposed as native CSS variables, accessible everywhere including JavaScript.
Native container queries
<div class="@container">
<div class="@lg:flex @lg:gap-4">
<!-- Adapts to container, not viewport -->
</div>
</div>
Real-world examples
Responsive contact form
<form class="max-w-lg mx-auto p-6 bg-white rounded-xl shadow-lg">
<h2 class="text-2xl font-bold text-gray-800 mb-6">Contact Me</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Name</label>
<input type="text" class="w-full px-4 py-2 border border-gray-300 rounded-lg
focus:ring-2 focus:ring-blue-500 focus:border-transparent
transition-all duration-200">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Email</label>
<input type="email" class="w-full px-4 py-2 border border-gray-300 rounded-lg
focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
<button type="submit" class="w-full py-3 bg-blue-600 text-white font-semibold
rounded-lg hover:bg-blue-700 active:bg-blue-800
transition-colors duration-200 shadow-md hover:shadow-lg">
Send
</button>
</div>
</form>
Service card
<div class="group relative bg-white rounded-2xl p-8 shadow-md
hover:shadow-xl transition-all duration-300 hover:-translate-y-1">
<div class="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center
group-hover:bg-blue-200 transition-colors">
<!-- Icon -->
</div>
<h3 class="mt-4 text-xl font-semibold text-gray-900">Web Development</h3>
<p class="mt-2 text-gray-600 leading-relaxed">
Custom websites, performant web applications, and e-commerce solutions.
</p>
<a href="#" class="mt-4 inline-flex items-center text-blue-600 font-medium
hover:text-blue-800 transition-colors">
Learn more
<svg class="ml-1 w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
</a>
</div>
When not to use Tailwind
Tailwind is not universal:
- HTML emails: inline CSS is preferred
- Dynamic CMS content:
@applycan help but remains limited - Teams without training: the learning curve exists
Conclusion
TailwindCSS has proven that the utility-first approach is not a compromise but an improvement. Version 4 reinforces its strengths with exceptional build performance and simplified configuration.
For my freelance development projects, Tailwind has become a standard. The development speed, design system consistency, and minimal production bundle sizes make it an obvious choice for any modern web project.
Migrating from traditional CSS
If you’re working with an existing codebase, Tailwind supports gradual migration. You can run Tailwind alongside your existing CSS and progressively replace styles:
- Install Tailwind and verify it works alongside your current CSS
- Add a prefix to Tailwind classes to avoid conflicts (
tw-) - Migrate one component at a time
- Remove old CSS once no component references it
- Remove the prefix once the migration is complete
This gradual approach avoids risky big-bang rewrites and lets you adopt Tailwind at your own pace.
Performance in production
Real-world performance data shows that Tailwind sites consistently produce smaller CSS bundles than Bootstrap equivalents. A typical Tailwind production build for a marketing site with 20 pages generates 6-12 KB of CSS (gzipped), compared to Bootstrap’s 22-25 KB even with unused component removal.
Because Tailwind classes are short and repetitive, they compress extremely well with Brotli or gzip. The repetitive nature of flex, p-4, text-sm across your HTML means high compression ratios. The trade-off is slightly larger HTML files due to class lists, but HTML also compresses well, and the combined size (HTML + CSS) is almost always smaller with Tailwind than with traditional CSS approaches.