Best Practices

I Used Tailwind for 6 Months, and Here’s What I Learned

Exploring Tailwind CSS
  • LinkedIn
  • YouTube

As a front-end developer, we know how overwhelming choosing a styling technology can be. There are hundreds of options right there. Some preferred vanilla CSS due to its simplicity and wide support across all browsers without additional configurations. Other developer like CSS-in-JS since it’s easy to maintain, especially when using a framework like React where you can separate styles based on components; this gives scope to component styles, making it less-susceptible to style conflicts.

Lately, Tailwind CSS has been gaining popularity in the front-end space. Tailwind CSS adopts a utility-first approach, which boosts productivity and consistency by using predefined classes directly in your HTML. As developers who work on a team, this can help promote uniformity throughout your projects.

That is why I decided to dive into Tailwind CSS a few months ago. I want to see for myself if tailwind will be a technology worth using in my future projects. In this article, I’ll share my experiences and insights after using Tailwind CSS. We’ll explore the advantages and disadvantages, how to manage its quirks, and how it stacks up against Vanilla CSS and CSS-in-JS solutions.

The Advantages of Tailwind CSS

Rapid Development

One of the main arguments for using Tailwind CSS is its ability to accelerate the development process.

Story Image
Story Image

By leveraging these features, developers can build and style components much faster compared to traditional CSS methodologies. Tailwind CSS reduces the boilerplate code, provides a standardized design system, and enables rapid prototyping and iteration.

Consistency and Customizability

Tailwind promotes a consistent design system OOTB to ensure your app remains uniform across different components and pages. You no longer have to worry about uneven spacing, colors and typography. Others may find this restrictive or this can make websites across the web look identical to each other. Especially those who used old styling technology but this isn’t the case here. Although they provide predefined styling, tailwind still gives you the freedom to fully customize your projects based on your preferences and business needs.

Story Image
Story Image

Performance

Unlike vanilla css and css-in-js where you can easily overlook unused stylings in Tailwind you don’t have to worry about this kind of stuff. By using PostCSS and PurgeCSS, tailwind removes unused styles from your final build, resulting in faster load times and smaller CSS files. Although such a process is hardly noticeable in small projects — Its impact becomes significant in large-scale projects.

Tailwind CSS provides a framework for rapid development, promotes consistent design, allows for extensive customizability, and optimizes performance by removing unused styles. These benefits make it a powerful tool for modern web development.

The Disadvantages of Tailwind CSS

Just as there are good parts, there are also bad parts. I will discuss the disadvantages I observed as I used it and try to provide a way to minimize them in a later section.

Story Image

Readability

One of the main complaints and what keeps other developers not wanting to touch Tailwind is its readability. With multiple utility classes (p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md space-y-4 etc.). applied directly to elements, your markup can become messy and harder to understand. This is true especially with untrained eyes. I too had this kind of complaint at the beginning of my journey but this is hardly the case with enough time and practice.

Learning Curve

While Tailwind is powerful, it does come with a learning curve. After all, you’ll have to learn a new set of utility classes and change your old habits while using traditional CSS or even CSS-in-JS. For example, classes like space-x-4, flex-shrink-0, and hover:bg-blue-600 are specific to Tailwind and require learning Tailwind's conventions and naming scheme. Albeit powerful, Tailwind’s configuration file can be complex for beginners. Understanding how to customize the default theme, extend utilities, and purge unused CSS efficiently requires a deeper understanding of Tailwind's configuration options. This additional layer of complexity can be a hurdle for those new to the framework.

Lack Semantic Classes

Tailwind utility classes are functional but not semantic. Making it harder to understand the purpose of an element at a glance. This can be a problem for those developers who like to have meaningful HTML class names.

The utility classes used here (p-6, max-w-sm, rounded-xl, etc.) do not convey the purpose of the elements. Unlike semantic classes (like .card, .card-header, .card-body), these utility classes are purely functional. This can make the code harder to understand for others who prefer meaningful class names that describe the role of each element.

Despite the challenges mentioned above, once a developer becomes proficient with Tailwind CSS, the benefits of rapid, consistent styling and the power of utility-first CSS can significantly enhance productivity and maintainability in large projects. However, these initial hurdles can be daunting for beginners or those accustomed to traditional CSS practices.

Keeping Tailwind Manageable

Techniques to Mitigate Readability Issues and Maintain Clean Code

To address the readability issues, one effective way is to use different directives. There are a lot of directives in Tailwind, each with their own use case, but for now, let’s use @apply as an example. Sometimes you will find yourself repeating the same design classes over and over again, and one way to mitigate this issue is to make them reusable. @apply does just that. It helps encapsulate and reuse utility classes by using your own custom class name.

Although you might think this defeats the purpose of using Tailwind, You might as well use traditional CSS at this point. You’re right, but sometimes you need to override third-party libraries, and one way to do that is to use this method. And this is also helpful to further simplify the design system for your project.

Story Image

As you can see, you can save a lot of time by doing this as opposed to typing them over and over again.

Helper Functions

Helper functions in JavaScript or utility-first design tokens can also improve manageability. By abstracting common utility combinations into helper functions, you can reduce repetition and enhance readability.

  • Design Helper Functions
Story Image
  • Use Helper Functions in Components
Story Image
Story Image

You can also use third-party packages such as `tailwind-merge` and `clsx` to make using utility classes more dynamic and flexible.

There are more ways to make your Tailwind project manageable; these are just a few of many ways. You can abstract common utility combinations into helper functions, improving the readability and maintainability of your Tailwind CSS code.

These approaches help keep your HTML clean and ensure that your styles are consistent and reusable across your project.

Component Libraries

Incorporating component libraries that are designed with Tailwind in mind, such as Tailwind UI or Headless UI, can help maintain consistency and cleanliness in your codebase. These libraries provide pre-designed and highly customizable components that follow best practices, saving time and effort.

Comparing to Vanilla CSS and CSS-in-JS

Vanilla CSS

Pros Compared to Tailwind

Simplicity - Vanilla CSS is straightforward and doesn't require learning new syntax or methodologies.

Semantic Naming - Promotes meaningful class names, enhancing readability and maintainability.

Cons Compared to Tailwind

Development Speed: Slower due to the need for separate stylesheets and frequent context switching.

Consistency: Harder to maintain a consistent design system without a framework.

CSS-in-JS

Pros Compared to Tailwind

Scoped Styles - Styles are scoped to components, reducing the risk of conflicts.

Dynamic Styling - Easier to apply dynamic styles based on props and state.

Cons Compared to Tailwind

Complexity: Can add complexity to the codebase, especially in large applications.

Performance: Potential for larger bundle sizes and runtime performance overhead due to inline styles.

Conclusion

Recap

After several months of using Tailwind CSS, I've found it to be a powerful tool for rapid, consistent, and responsive web development. Its utility-first approach can significantly speed up the development process and ensure a cohesive design system. However, the trade-offs include potential readability issues, a learning curve, and less semantic HTML.

Personal Verdict

Overall, Tailwind CSS has become an essential part of my toolkit. While it has its challenges, the benefits it offers for speed, consistency, and performance outweigh the drawbacks. For projects where rapid development and a consistent design system are priorities, Tailwind CSS is an excellent choice. For teams focused on semantic HTML and minimizing learning curves, a more traditional approach with vanilla CSS or a scoped styling solution like CSS-in-JS might be preferable.


About the Contributor

Discuss this topic with an expert.