Tailwind CSS: A critique
Tags: webdev, tailwindcss, css, design
Published: 2023-02-01 20:37:11

Tailwind CSS has grown increasingly popular for its utility-first approach to styling HTML. While it offers several advantages, such as design uniformity and extensibility, it also has its set of challenges, including lack of abstraction and repetition. This essay aims to offer a balanced perspective on Tailwind CSS, providing insights that could guide your decision to use it in your projects.

### Design Constraints
One of the most appealing features of Tailwind CSS is its design constraints. These constraints enforce a uniform look and feel across all components of a website.

### Extensibility & Configuration
Tailwind provides a configuration file that offers incredible flexibility, allowing developers to create any number of CSS properties. It even supports Just-In-Time (JIT) compilation, enabling the use of arbitrary values directly in your markup, similar to inline CSS.

### Preflight
Tailwind's Preflight is a robust normalization feature built on top of [modern-normalize](https://github.com/sindresorhus/modern-normalize). It harmonizes default styles across different browsers and offers a multitude of other features, such as easy-to-set borders and a reset of browser styles. Preflight is so useful that I would consider using it even in projects that don't utilize Tailwind.

### Lack of Abstraction
Tailwind CSS does not abstract away from the underlying CSS, often resulting in class names that aren't much better than using inline styles.

### Repetition
The framework falls short when it comes to creating reusable components. As illustrated in the following code snippet, the utility classes can become quite verbose and repetitive.

```html
  <div class="mt-3 flex -space-x-2 overflow-hidden">
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80" alt=""/>
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1517365830460-955ce3ccd263?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
  </div>
```

Tailwind does acknowledge this shortcoming but offers solutions that are not entirely satisfactory. You can either adopt another framework, which might not be desirable for everyone, or use their `@apply` directive, which doesn't fundamentally solve the problem.

> #### Note
> Since writing this I've discovered that using [Tailwind's plugin for prettier](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) sorts valid tailwind classes, allowing repetitive classnames to be easily compressed when using gzip or brotli. This means that verbose class names have virtually zero impact on the end user or SEO.

### Conclusion
Tailwind excels in rapid prototyping and in its capacity to adhere to a design system through extensibility. Its Preflight feature is notably excellent and could benefit more projects. However, it does struggle with verbose and sometimes unmaintainable class names, leading to inflated HTML file sizes. 

Thanks for reading! If you take one thing away from this essay, consider incorporating modern-normalize into your future projects for more consistent cross-browser styles.