Why I Use Tailwind
I am admittedly a big fan of Tailwind, but for one primary reason: it makes me more productive. It may do the same for you. It may not. Perhaps you love the power and flexibility of vanilla CSS. Or a CSS-in-JS library makes the most sense for your situation. Or you’ve forgotten more about SCSS mixins than I will ever know. That’s fine. No tool is right for every person and every project. But for me, Tailwind hits a lot of right notes that let me build and create UIs more seamlessly.
Here is an unordered, non-exhaustive list of what I like about Tailwind:
- It gives me good guardrails for design. I am not a designer. In fact, a blank white screen hits me with a particularly strong bout of paralysis. Tools that can help me design better by default are crucial. From the color palette to the spacing system, I can build UIs using Tailwind classes and it generally looks good without me having to try too hard.
- It helps me pattern match across projects. Using Tailwind has a flywheel effect. I’ve used it across half a dozen projects now and each time I use Tailwind, I’m that much faster implementing it. Additionally, even if the overall designs vary widely, the underlying Tailwind classes are essentially the same so there’s less context switching regarding design when I switch projects.
- It gives me flexibility when a design is still emerging. Going back to the “blank white screen” comment above, there are times when I don’t know what the design is going to be yet. I need to change and edit as I go to see what emerges from my tinkering. I find Tailwind classes to be helpful here since it’s trivial to add or remove classes from HTML elements.
- It helps me prototype quickly. This is closely related to the item prior. It’s trivial to add and remove HTML classes. That combined with the fact that Tailwind allows me to design in my templates, e.g. I can style using pre-defined classes instead of having to switch to another file + syntax such as CSS or SCSS, means that I can crank out prototypes with less context switching.
- It is highly portable. With a few exceptions, one can copy/paste Tailwind classes from one project to another and it will Just Work™. There are a few places where this breaks down, specifically when using plugins or with custom classes. Otherwise, it’s so effective, this is essentially what the Tailwind UI kit is: copy/paste-able code snippets with all the classes predefined.
- It optimizes for deletion. This is especially helpful for larger and/or older codebases. Many times, long-lived CSS files tend to devolve into an append-only mode. In other words, no one knows the ramifications of removing certain CSS rules because it’s difficult to know if they’re still being used so the CSS file only grows. Contrast that with classes that are applied directly in your HTML or templates. When I delete code that uses Tailwind classes, Tailwind will handle removing any classes that aren’t in use anymore. Nothing extraneous hangs around bloating our builds or has to be cleaned up later.
- It still allows me to write vanilla CSS and compose new classes. Tailwind itself is a PostCSS plugin which means we can still write perfectly valid and normal CSS alongside our Tailwind usage. For example, there may be a particularly complex layout or animation that requires more CSS than what is exposed by Tailwind. In these cases, we can write CSS as we normally would. We can also use the
@apply
directive in our CSS to piggyback off of the Tailwind classes we’re already using elsewhere, i.e. we can use@apply text-blue-500
to get the same color text as using that class in our HTML. - It lets me extend it. Tailwind allows both customizing the default values that are used by Tailwind as well as extending it with new classes. Don’t like the shades of orange that comes with Tailwind? You can easily swap it out. Just about every base value in Tailwind can be customized if one so desires. And because Tailwind is a PostCSS plugin, it is able to provide a set of functions that allow 3rd-parties to create reusable plugins that add new classes to Tailwind. One of the key areas where this differs from simply writing custom CSS classes is that classes added via plugins can be combined with all the typical modifiers.
- It has great docs and supporting resources. The first-party docs from the Tailwind team are very well written and contain a wealth of information. I’ve also found the Tailwind cheat sheet to be an invaluable resource, especially when first learning Tailwind. There’s strong IDE integrations with VS Code (which I’ve used and it is stellar) and JetBrains IDEs. There’s also UI libraries like Tailwind UI and Headless UI that provide lots of functionality with Tailwind classes used for styling.
I’d be lying if I said there weren’t any tradeoffs though. As with any technology, it doesn’t work for every person and situation. Here are some of the things I’ve found difficult about Tailwind:
- It requires a specific build process. Depending on your dev setup, there may be extra work required to get Tailwind working. This is becoming a little easier as more tools are providing Tailwind integrations. create-react-app just added out-of-the-box Tailwind support in their most recent major release. There’s also the Play CDN as well as the standalone CLI tool, the latter being used by projects like Elixir’s Phoenix Framework to remove their Node.js dependency entirely.
- Your HTML can get muddled with CSS classes. This may be one of the most polarizing aspects of Tailwind. If you are styling anything non-trivial, you’ll probably end up with quite a few classes on a single HTML element. For some people, this isn’t a problem. For others, it’s a huge sticking point. Personally, it took some getting used to but I adjusted quickly. I’ve found this to be less of a problem if there’s solid encapsulation and code reuse via some componentization mechanism. There’s also a recently-released Tailwind Prettier plugin to automatically order Tailwind classes which should make it easier to parse through when they’re always in the same order.
- The cascade may not be what you expect. This may take you by surprise especially if you’re coming from a CSS-in-JS library where conditionally applying styles just works, but trying to override the text color for example isn’t as simple as adding a second text color class to an element. Ideally, one would remove the first text color class and add the second. CSS classes do not apply themselves based on the order they are listed in the HTML. They apply based on the CSS cascade using a combination of selector specificity and position in the CSS file. And the way Tailwind generates its CSS, the text color class order in the CSS is an implementation detail that shouldn’t be depended on.
- There is a somewhat steep learning curve. Especially when one first starts, there are a lot of classes. A lot. And it will take a while before using those classes becomes second nature.
There you have it. The good and the bad, from my perspective, on Tailwind. I highly recommend trying it out if you haven’t yet. It may feel strange at first, but the productivity gains can be enormous. That is, after all, why I use it.
Have thoughts about Tailwind? Chat with me about it on Twitter!