Tailwind CSS – What's the Big Deal Anyway?
This is part two of a two part analysis on Tailwind CSS – link to part 2.
Few Front-End tooling discussions are as contentious as the debate around Tailwind CSS. Like eating raw fish or reading poetry, you either love it or hate it.
Maybe you've heard both sides of the argument and are wondering if learning Tailwind is necessary as a CSS beginner. Or you've skimmed at the docs but don't understand its utility.
If you are asking yourself "Why is Tailwind CSS such hot stuff?" – this post is for you.
I'll list my reasons why Tailwind CSS could be the right CSS framework for you or your team. While I only use Tailwind for my personal projects, I just spent the last few weeks auditing CSS stylesheets from a few different teams in my company and Tailwind definitely could improve some of them.
The Skinny on Tailwind
So what is Tailwind CSS? It is a utility-first CSS framework that takes the atomic approach to styling. Every allowed CSS value gets a class name. For example, md:py-8
applies size 8 padding in the y-axis under medium viewport size and above. You then stack the class names together to achieve the style you want.
As an example, a fully style div in Tailwind would look something like this:
<div class="py-8 px-8 max-w-sm mx-auto bg-white rounded-xl shadow-lg space-y-2 sm:py-4 sm:flex sm:items-center sm:space-y-0 sm:space-x-6" />
Which is roughly equivalent the following CSS:
div {
display: flex;
max-width: 24rem;
margin: 0 auto;
padding: 1.5rem;
border-radius: 0.5rem;
background-color: #fff;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
@media(max-width: var(--viewport-small)) {
padding: 1rem;
display: flex;
margin-top: 0px;
align-items: center;
}
Some folks simply couldn't get over the abundance of class names for what is essentially short-hand inline CSS. Tailwind classes act as an API layer on top of existing CSS properties, leading to some extra cognitive overhead. When I use tailwind, I always have the docs open.
On the other hand, fans swear by the Framework. It seems to cure everything from large CSS files to rheumatoid arthritis. A lot of the rationale is in the 'you gotta use it to believe it' category – including the Tailwind Docs – so I'll break down its benefits from my perspective.
Note: For a full explanation of what Tailwind is and how to use it, check out its excellent documentation. This post is my opinionated take on why Tailwind CSS works well for some teams.
Configurable Design System
I often see Tailwind called 'CSS shortcut' or compared to vanilla CSS. Truth is, it's both more and less than that. Take this testimonial from the Tailwind homepage:
I have no design skills and with Tailwind I can actually make good looking websites with ease and it's everything I ever wanted in a CSS framework.
If Tailwind is just CSS shortcuts, then how would produce better-looking sites? It wouldn't. Tailwind out of the box is already opinionated, it has built-in defaults for font scale, color palette, and spacing scale. It's these constraints that allow a non-designer to create good-looking sites.
What separates Tailwind from other CSS frameworks like BootStrap and Material is how easily customizable it is. While default Tailwind is opinionated, its opinions are very weakly held. This means you get the power of a full-fledge design system but with the customizability of vanilla CSS. Be warned though, Tailwind's default values are tweaked by professional designers, so your customization may not look as good.
This also means Tailwind is great for prototyping and MVP creation. Once your product is mature, the bar for updating default Tailwind styles with your own Design System is low. It's much lower than Bootstrap or MUI.
Benefit One: Tailwind forces devs to work with a customizable Design System.
The Selector Problem
For me, using CSS selectors is a bit like going to a buffet, I always end up with more stuff on my plate than my body needs.
The root of the problem is there's often no predictable cause-and-effect. Fundamentally and outside of globals, we tend to only make changes to one part of a page at a time. But CSS selector's ability to cast a wide net and the cascade's ability to propagate that change down the CSSOM, all too often we change more than what we originally intended to. And always in unintended ways. To borrow an old CSS joke:
This problem is especially painful for large teams or codebase with external CSS usage. With tight deadlines and new team members, it's not uncommon to trace a style bug into some weird corner of the attic under line 45 of overwrites.css
.
Solutions to the selector problem fall in a spectrum. On one extreme you see folks abandoning selectors entirely via inline style or Styled Components. On the other extreme, you have rigid selector layers such as ITCSS. The goal? Give every selector a home where it belongs. Tailwind's atomic CSS philosophy is also somewhere in the middle and closer to inline style. All CSS styles belong to one class – @apply is an antipattern – and the class is only responsible for one or at most a few CSS properties.
No specificity overwrites are needed. No stylesheets to organize. No need to come up with descriptive class names just to hang selectors on.
Benefit Two: Tailwind makes managing a large codebase easier by flattening selector levels and removing stylesheet organization.
Ready-Made Workflow
Another Tailwind benefit often not talked about is it's a complete and sensible workflow in a box. You are not just buying into the framework, you are buying into a way of styling your website. A darn good one at that too.
Tailwind forces a comprehensive designer/developer handoff process. Before a single line of CSS is written, a developer must translate the designer's specs and scales into the project's `tailwind.config.js`. None systematic values are simply not exposed via Tailwind. Though turning design style guides into Sass / CSS variables is a part of generally accepted styling practices, in practice, this step often gets overlooked or is not continuously worked on.
In day-to-day development, devs are only working with the HTML component they are currently working on. Cognitive capacity once used for selector wrangling, class name creation, and CSS context management is freed up to only work on choosing the right class for the job.
According to the Mythical Man-Month, additional manpower added to a project often slows it down due to the exponential growth of communication channels. With Tailwind, gone is the need to enforce BEM sensibly across a codebase. No more one-off pixel value "just to match the design". No more debates on when a set of styles should be abstracted into utility classes.
Benefit Three: Tailwind is CSS on Rails. It's especially helpful when you need a Design System 'that just works!' or have a large Front-End team with few documented styling guidelines and no time to build/enforce them.
I urge you to give Tailwind CSS a try if you are currently CSS framework shopping, or if you have a frontend project that 'just needs some style' but don't want to be stuck with 'that Bootstrap look'.
I hope I did a good enough job to convince you that Tailwind is a game-changer that every developer should consider. Link to part two on the downsides of using Tailwind CSS.
If you found this post interesting and haven't done so already, check out my post on creating Styling API with CSS Custom Props for an alternative solution to better styling through Design Systems.
Big Idea of the Week 3/1/2022
Trying something new this week. Going forward, I will share a single 'Big Idea' that made me go 'Woah!' every week.
This week's Idea comes from Rob Fitzpatrick's book The Mom Test. It's about talking to customers to validate your ideas. Here's the idea:
Never ask anyone 'will you use my product?' in a future tense, ask about 'when was the last time you faced the problem (that my product solves)? what did you do?'
A simple and powerful 'reverse logic' technique for cutting through polite white lies and our approval-seeking egos. Future promises are not data, only past actions count.
Let's pretend we are validating the idea of a utility first CSS framework.
Do not ask:
"Will you use a utility first CSS framework that has a unique class name for every CSS prop value pair?" – Woah, that sounds like an ugly nightmare, but I will say yes just to be polite.
Ask:
"When was the last time you saw an inconsistent spacing value in a design deliverable and what did you do about it?" – Oh yeah! Like just last week there was a weird 4px margin on the product page even though we generally use 6px margins for our images, but I didn't say anything since it's the designer's job, plus I was in flow and it sucks to waste 20 minutes going back and forth with the designer...
I love the idea and I hope you found it interesting too! Reply to this email or ping me on Twitter and let me know if you agree or disagree!