TailwindCSS has been rapidly rising to popularity in the last few years, and it's easy to understand why - it makes styling your web apps far easier, letting you rapidly develop designs on the fly without needing to handle a scalable CSS system.
But despite seeming better to use than vanilla CSS, Tailwind has its tradeoffs, and perhaps it's time to stop using the now legendary framework.
In this three-part post, we'll look at how Tailwind came to be, where its promises fail, and how you can still create beautiful and accessible web apps without it.
The Tailwind Story
Inspiration & Creation
Tailwind was created by Adam Wathan, an open-source web developer. At the time, Wathan was working on a side project, a web app that would allow users to share articles with their team.
Up till then, Wathan had used Bootstrap for everything, but at the time decided to switch to using his own CSS, as Bootstrap switched from Sass to Less. As he would later say in an interview, "And I just like dogmatically loved Less and I didn’t want to stop using Less... [if] I want to keep using Less, then I have to write CSS myself" (Wathan).
Over time, Wathan found that he kept on reusing the same base set of utility styles - small classes that would add padding, center text, or perhaps turn an element into a flexbox container.
"[if] I want to keep using Less, then I have to write CSS myself"
Wathan would stream his web creations for people to see, and at the time didn't think much of the CSS, instead focusing on the rest of the web app. During the livestreams, however, audience members began to take notice, and wonder about the approach to styling.
Around the same time, a friend of Wathan, Jonathan Reinink, was about to do a large design of a SaaS product and decided to try out Adam's approach. From there, the steps were clear - Adam would end up extracting his styling approach into a library, which we today know as TailwindCSS.
Thinking in Tailwind
TailwindCSS provides small, utility-based classes that can build up to create your application - an approach we today call atomic CSS.
Take the following example of a contact card, written with TailwindCSS:
<figure class="bg-slate-100 rounded-xl p-8 dark:bg-slate-800">
<img class="w-24 h-24 rounded-full mx-auto" src="...">
<div class="pt-6 text-center space-y-4">
<blockquote>
<p class="text-lg font-medium">
...
</p>
</blockquote>
<figcaption class="font-medium">
<div class="text-sky-500 dark:text-sky-400">
...
</div>
<div class="text-slate-700 dark:text-slate-500">
...
</div>
</figcaption>
</div>
</figure>
Rather than styling each element with CSS, Tailwind provides a large set of utility classes that can easily be attached to elements, allowing for styling as you create the content of your web app.
If you have a common set of styles for a specific case, for example, a primary style for buttons that you use across your web app, you can also use Tailwind's builtin @apply decorator in CSS:
.button-primary {
@apply p-6 text-center text-sky-500 bg-slate-100;
}
How it Works
At first glance, it might look like Tailwind's providing a CSS file filled with classes - but when you throw hundreds or perhaps thousands of lines of CSS into a web app, performance can take a big hit.
That's why Tailwind relies on PostCSS, a tool that lets JavaScript transform and manipulate CSS. That allows Tailwind to only apply styles for used classes, and even automatically apply browser prefixes for compatibility.
However, despite the optimization techniques used, Tailwind is still a relatively large drag for performance, especially for smaller web apps that don't necessarily need the massive engine.
Why it's Time to Stop
We've now looked at what Tailwind is, and it's easy to see why it's grown so popular - it reduces the need to plan and organize, letting you instead exercise creativity and style on the fly.
Thinking Backwards
That being said, it's time to stop using Tailwind. First, there are the obvious drawbacks: Tailwind takes up performance and storage, not to mention the fact that it generates long, bloated markup files that are hard to read. There are workarounds - extensions that will hide classes in your editor until you click on them, and alternatives like UnoCSS that are even faster.
But the real problem with Tailwind lies in the thinking itself. While at first, it can seem like Tailwind is far faster and more scalable than typical CSS, it takes more and more resources as your web app grows, and makes it hard for others to understand your code.
But the real problem with Tailwind lies in the thinking itself.
In addition, Tailwind's method of styling produces tight coupling, where the structure and styling of your app are bound together. That makes it hard to make changes across your web app, and is considered bad practice.
Shortcut, not Superior
In essence, Tailwind acts like a shortcut - useful in the beginning, but a drag in the long run. Is Tailwind easier? Compared to CSS, it certainly can feel a lot easier - but you'll find yourself moving faster and with greater creativity by embracing structure and coordination instead of Tailwind.
You'll find yourself moving faster and with greater creativity by embracing structure and coordination.
As Tero Piirainen, creator of Nue, writes, "Loose coupling makes you think content first. There is no need to write a component for every situation because you can use external CSS to do the heavy lifting".
The Semantic Way
OK, you might think - Tailwind isn't as great as it seems - but now what? It can be hard to leap right into building CSS for your web app from scratch, which is why we'll look at one way of doing it.
Not All Bad
Although the framework itself isn't what we want, Tailwind itself is a great design resource. Its utility classes provide great presets for sizes, widths, and other presets, and it also automatically resets default browser styles, something you should almost always do.
You can use @unocss/reset to erase browser styles like Tailwind, and Tailwind's documentation has all the CSS that its classes provide. I find myself using the colors, font sizes, and border radiuses the most - copy the styles provided in the table.
Styling with CSS
Let's take a look at the contact card example from earlier, and now style some of it using semantic CSS:
<figure>
<img src="...">
<div>
...
</div>
</figure>
<style>
figure {
padding: 8rem;
border-radius: 0.75rem;
background-color: #1e293b;
}
figure > img {
width: 6rem;
border-radius: 100%;
margin: auto 0;
}
figure > div {
padding-top: 1.5rem;
text-align: center;
}
div > * + * {
margin-top: 1rem;
}
</style>
At first, it might just seem like we've wasted a lot of time and generated more lines of code - but you'll notice it's a lot easier to understand what's going on now, and as this project grows, styles will naturally fall into place in a structured way.
Conclusion
Overall, it's better to take the time and effort of organizing styles with semantic naming, rather than using shortcuts like TailwindCSS and other atomic frameworks. Your web apps will scale easier, be more readable, and perform better than before.
SOCIAL SHARE CARD GENERATOR