So, what is it?
If you're not already familiar with TailwindCSS, it's a CSS framework focused around using utility-based classes. Essentially, Tailwind provides a ton of utility classes for everything from setting colours (background, font, border etc.), font size / weight, to layout helpers for css grid and flexbox.
The main tagline is:
Rapidly build modern websites without ever leaving your HTML.
How it achieves this goal is via the use of utility classes. No longer do you have to switch back and forth between HTML and CSS. Before using it, my own opinion on this would have been that this would easily get out of hand. Sure it may be fine for a basic layout, but how would this look for even a simple button component. One where you'll need to have different variants, handle state changes for hover, focus, disabled etc.
Put (Tail)wind in your sails
So why should you use it over regular good old css, semantic class names or even the old reliable - bootstrap.
To quote the creator of TailwindCSS, Adam Wathan:
"Best practices” don't actually work.
I've written a few thousand words on why traditional “semantic class names” are the reason CSS is hard to maintain, but the truth is you're never going to believe me until you actually try it. If you can suppress the urge to retch long enough to give it a chance, I really think you'll wonder how you ever worked with CSS any other way.
This is front and centre on the homepage, and basically in his opinion, the old fashioned way of creating semantic class names to apply your styles isn't great. He goes into a lot more detail in his post, but the gist of it is that taking a utility-first approach will help resolve many common pitfalls around consistency in the former approach.
And honestly this resonates with my own opinion before I'd actually given it a solid go, but after using it for the past few months, it feels both strange and slower to go back and write css the way I used to.
So, if you're not already familiar with the utility-based approach, it can initially look quite messy. The examples shown below are of some baseline classes to style a button and that's not even all of them, more will be applied to change the colour, size etc. based on the variant selected.
An example of a few class names applied to a button component
The CSS styles that the Tailwind classes would translate into
In the second image, you can see a rough translation of how these classes would be written in normal css. The approach TailwindCSS uses may put you off, but if you look at it closely, you'll see the styles are generally grouped together in relevant sections. For example, all the focus styles are next to each other and the styles relevant to the layout for flex are next to each other, and so on. This was done automatically by using the Prettier plugin.
The Case for the Defence
Okay, now that we know the philosophical approach behind Tailwind, why would you use it? Here are the key points for the defence:
1. Clarity / Understandability
All of the styles that can be applied to an HTML element are specified in the class attribute of the element, including all of its various states e.g. focus, hover, etc. This means that an element's applicable styles can be understood simply by examining the element. This information is typically scattered across the HTML and the CSS, making traditional CSS harder to manage, especially at scale.
While projects using CSS may have many different ways of doing things, Tailwind enforces a consistency in it's naming conventions and how it's styles are applied through its class names, which:
- Enforces consistency via naming, and provides powerful ways of adding one off styles e.g. using arbitrary values.
- Allows for certain fallbacks to be added automatically e.g.
Utility classes can be combined to create ever more intricate stylings to an element. Tailwind is like the declarative equivalent of well-written imperative or FP code. You end up with far more small functions, each doing one thing, and end up with far less code overall to manage and maintain. This becomes an increasingly important attribute as systems increase in size. Tailwind's real value is at scale.
4. Faster Development
As you can update styles without changing context, everything is done in the same file. Some may look at that as a disadvantage, but in this juror's opinion it's definitely a faster way to work, plus you can reason about an element's style more easily.
It can help with using new CSS features without worrying about compatibility, having to implement fallbacks/polyfills etc.
Tailwind's CLI tool will only include the classes you use in the output css file. Since many of these classes will be reused, the end result can be very efficient.
It has excellent IDE support with a range of plugins that help make it more accessible and easy to use:
- Plugins for IDE's to provide autocomplete on classes (including custom classes for any colours or typography you've added.
- The Prettier plugin can be used to auto-sort and group the class names so that your class attributes are easier to read and reason about.
8. Fantastic Documentation
Tailwind's documentation is exceptional and features many useful examples of the classes in use. This is great for anyone with less experience using CSS, or even those who haven't kept up to date with the ever-evolving standards.
The Case for the Prosecution
The case for the prosecution centres on 3 main witness statements:
Having lots of classes in the HTML means that the HTML can look significantly more verbose than the semantic class name approach, although this can be partially mitigated through use of the plugins above (and toggling word wrap in your IDE) and having less and simpler actual CSS.
You can use
@apply to extract and reuse the styles (though this is only recommended for small and highly reused content like form controls e.g. inputs, buttons etc.).
Creating components with multiple variants (e.g. a button with a primary, secondary, tertiary appearance) is more effort than the semantic equivalent.
- To help with this, there's a great library called class-variance-authority (CVA) which will allow you to create typesafe components with mutliple variants.
- There's a great video on Vercel's YouTube channel about building out a component library for Next.JS using TailwindCSS and CVA.
It can take a while to get used to the syntax and different prefixes used, although once you get used to the patterns, this will become second nature.
For me, this is a pretty open-and-shut case. Whether you're already familiar with CSS or completely new to it, I believe the benefits of Tailwind far outweigh any perceived downsides. Without any reasonable doubt, I would recommend giving it a go in your next project.