Skip to content
THE GUILD
0%
Services Products Careers About Us Blog FAQ Contact
It Looks Awful, But It Works: Why Tailwind CSS is Actually Brilliant

“There’s literally no words I could possibly say that will convince you that littering your HTML with dozens of presentational classes is actually a good idea.”

Those are the brutally honest words of Adam Wathan, creator of Tailwind CSS, speaking at Rails World 2023. He’s right—when you first see Tailwind code, it looks absolutely terrible. But here’s the twist: once developers actually try it, they have a completely different reaction.

The Shocking First Impression

Let’s be honest about what Tailwind looks like to newcomers:

Traditional CSS approach:

<div class="testimonial-card">
  <img class="avatar" src="profile.jpg" alt="Profile">
  <h3 class="name">Eric Lane</h3>
  <p class="title">Project Manager</p>
</div>

Tailwind approach:

<div class="bg-white rounded-2xl shadow-lg overflow-hidden p-1 pb-0">
  <img class="w-20 h-20 rounded-full outline-2 outline-white -mt-10" 
       src="profile.jpg" alt="Profile">
  <h3 class="font-semibold">Eric Lane</h3>
  <p class="text-sm text-gray-600">Project Manager</p>
</div>

Your first reaction? “This is insane!” And Wathan completely agrees. But here’s what he’s discovered after six years of building Tailwind: “Most people when they actually give it a try, they start to feel very quickly like ‘how the hell did I think writing [traditional CSS] was somehow a better idea?’”

The “Aha!” Moment: Live Coding Reveals the Magic

Instead of trying to argue why Tailwind is good, Wathan does something brilliant—he live codes entire components from scratch. Watching him build a complex profile card in real-time reveals something remarkable:

Speed That Will Blow Your Mind

  • No context switching between HTML and CSS files
  • Instant visual feedback as you type classes
  • No naming fatigue—goodbye to “what should I call this class?”
  • Everything in one place—styles right where you need them

Flexibility Beyond Traditional Frameworks

Unlike Bootstrap or Foundation that lock you into their design system, Tailwind gives you the building blocks to create anything:

<!-- Complex hover effects with zero custom CSS -->
<div class="group hover:scale-110 transition duration-200">
  <img class="group-hover:scale-110 transition duration-200">
</div>

The Responsive Layout Revolution

Wathan demonstrates something that makes traditional CSS developers weep with joy—responsive design that actually makes sense:

Responsive grid layout with Tailwind

<!-- Mobile-first responsive grid -->
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
  <div class="md:col-span-2 aspect-video md:aspect-auto">Hero Image</div>
  <div class="aspect-square">Square Item</div>
  <div class="md:col-start-1 md:row-start-3">Positioned Item</div>
  <div class="md:col-span-1 md:row-span-2">Tall Item</div>
</div>

The result? A Pinterest-style mosaic layout that would take dozens of lines of custom CSS, built entirely with utility classes. No media queries, no complex CSS—just readable, maintainable HTML.

Dark Mode Magic (No JavaScript Required)

While other frameworks struggle with dark mode implementation, Tailwind makes it trivial:

<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
  <h1 class="text-indigo-600 dark:bg-gradient-to-r dark:from-indigo-400 dark:to-sky-400 
             dark:bg-clip-text dark:text-transparent dark:text-3xl">
    Gradient text in dark mode!
  </h1>
</div>

Dark mode implementation with Tailwind

Want to dive deeper into dark mode possibilities? Check out the comprehensive dark mode documentation for advanced techniques and customization options.

The Secret Weapon: Data Attributes and State Management

Here’s where Tailwind gets really clever. Want a loading button that shows a spinner? Most frameworks require JavaScript to toggle classes. Tailwind lets you do it declaratively:

<button class="group" data-loading>
  <span class="group-data-[loading]:text-transparent">
    Pay Now
  </span>
  <span class="hidden group-data-[loading]:flex absolute inset-0 items-center justify-center">
    <svg class="animate-spin"><!-- spinner --></svg>
  </span>
</button>

One data attribute change controls the entire button state. No JavaScript class manipulation needed!

The Duplication Myth, Thoroughly Busted

Critics say: “But what about all that duplicate HTML?”

Wathan’s response: “Managing duplicate HTML is literally the entire problem domain that templating languages were designed to solve!”

<!-- Rails partial - write once, use everywhere -->
<% users.each do |user| %>
  <%= render 'user_card', user: user %>
<% end %>

Component reusability with templating

For simple elements like styled links, Tailwind provides @apply to extract utilities into custom classes:

.link-primary {
  @apply text-indigo-500 hover:text-indigo-900 focus:underline font-medium;
}

But Wathan warns: only use this for simple, single-element components. Complex multi-element components are better handled with partials.

Dynamic Theming: The Ultimate Flexibility

Here’s something that will make your jaw drop. Want to let users customize your app’s theme colors? Traditional CSS would require generating dozens of stylesheets. Tailwind handles it with CSS variables:

<!-- Set dynamic colors via CSS variables -->
<div style="--btn-bg: orange; --btn-hover: #ff8800; --btn-text: white;">
  <button class="bg-[var(--btn-bg)] hover:bg-[var(--btn-hover)] text-[var(--btn-text)]">
    Dynamically themed button
  </button>
</div>

Dynamic theming with CSS variables

The power? Your users can customize colors through your admin interface, and those changes instantly apply to complex hover states, focus rings, and any other interactive elements—no CSS compilation required.

The Maintenance Reality Check

Wathan drops this truth bomb: “Maintaining CSS is hard. There’s a reason there are courses and books and architectures with catchy names on different CSS methodologies. No one ever had a debate about how to write maintainable HTML.”

The numbers back this up:

  • Zero CSS specificity battles when everything is utilities
  • No mysterious side effects from changing one component
  • Instant understanding when you return to code months later
  • Delete with confidence—remove HTML, remove styles automatically

Why Traditional CSS Developers Are Converting

The testimony from developers who’ve made the switch is remarkable:

“I was skeptical for months. The classes looked ugly and wrong. But after building one project with Tailwind, I can’t go back. The development speed and maintainability are just incomparable.” - Senior Frontend Developer

“We cut our CSS bundle size by 60% and our development time by 40% after switching to Tailwind. The learning curve was worth it.” - Tech Lead

Developer productivity with Tailwind

The Learning Curve That Pays Off

Yes, Tailwind has a learning curve. You need to memorize utility classes and understand the spacing scale. But here’s the difference: you learn it once, and it applies everywhere.

Traditional CSS requires you to:

  • Learn new class names for every project
  • Understand complex inheritance chains
  • Debug specificity issues
  • Maintain growing stylesheets

Tailwind requires you to:

  • Learn utility classes (once)
  • Apply them consistently (everywhere)
  • That’s it.

Real-World Performance Benefits

Beyond developer experience, Tailwind delivers measurable performance gains:

  • Smaller CSS bundles through unused style purging
  • Better caching since utility styles rarely change
  • Faster load times with optimized CSS delivery
  • Reduced runtime costs from simpler stylesheets

The Verdict: It Works Better Than It Looks

Adam Wathan’s conclusion rings true for thousands of developers: “It looks awful, but it works pretty well.”

The framework that initially seems like a step backward turns out to be a leap forward:

Faster development without context switching
More maintainable code without CSS archaeology
Better performance with optimized stylesheets
Infinite flexibility without framework constraints
Team consistency with shared utility vocabulary

Ready to Try the “Awful” Approach?

If you’re still on the fence, Wathan has one piece of advice: just try it. Build one small component. Experience the workflow. Feel the speed.

Most developers who give Tailwind an honest try discover what Wathan learned years ago: sometimes the approach that looks wrong at first glance turns out to be exactly right.

The question isn’t whether Tailwind looks good in your HTML—it’s whether it makes you more productive, your code more maintainable, and your users’ experience better. And on all those fronts, it absolutely delivers.


Watch the Full Talk: Tailwind CSS: It looks awful, and it works - Rails World 2023

Get Started: Tailwind CSS Documentation

Community: Join the discussion on the Tailwind CSS Discord