Cover image for blog post: "How Tailwind CSS grew on me"
Back to blog posts

How Tailwind CSS grew on me

A journey turning skepticism and dislike into enthusiasm

Published onMarch 02, 20245 minutes read

Table of Contents

Tailwind CSS is an amazing tool that helps us style our websites quickly by using simple utility classes, over predefined styles, unlike traditional frameworks like Bootstrap or Bulma, for example.

Disclaimer:

The opinions below are based on my humble experience with Tailwind CSS. They might be wrong, but it’s just the way I’ve understood its usage. There’s always more to learn and explore, for sure.

The debate

I think ever since Tailwind CSS was introduced, there’s been a constant debate among developers on whether its usage is better or worse for development and building websites and whatnot.

It can be a bit overwhelming at first when we realize we kinda need to mix our CSS with our HTML, going a bit against the separation of concerns and adding more things to the HTML code than otherwise needed.

It also will take some time to learn using Tailwind CSS. While some utility classes are similar to the expected CSS properties and values, others can vary a little, making it slightly harder to remember or use intuitively.

And certainly, Tailwind CSS might not be the best first approach for people new to CSS. I think it’s really fair to suggest people learn plain CSS first, at least its basics because that will be the base and first steps to understand what Tailwind CSS is doing for us under the hood and also know what the classes we use do.

Anyway, let me walk you through the points that have helped me overcome those unfavorable things:

Prevent duplicated CSS

When we write our CSS, we might end up having something like the following:

styles.css
.card-one {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1rem 1.5rem;
}
 
.card-two {
  display: flex;
  flex-direction: row;
  align-items: center;
  padding: 1rem 1.5rem;
  gap: 1rem;
}
index.html
<div class="card-one">...</div>
<div class="card-two">...</div>

That looks okay; our HTML code is pretty clean, and we have our CSS organized for every component. But our CSS could eventually grow bigger and bigger. And it could get hard to maintain.

Now, let’s take a look at our code if we used Tailwind CSS instead:

styles.css
.flex {
  display: flex;
}
.flex-col {
  flex-direction: column;
}
.items-center {
  align-items: center;
}
.justify-center {
  justify-content: center;
}
.px-6 {
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
.py-4 {
  padding-top: 1rem;
  padding-bottom: 1rem;
}
.flex-row {
  flex-direction: row;
}
.gap-4 {
  gap: 1rem;
}
index.html
<div class="flex flex-col items-center justify-center px-6 py-4">...</div>
<div class="flex flex-row items-center px-6 py-4 gap-4">...</div>

For this short example, we have more lines of CSS code, yes. And it kinda looks like I have failed to make a point in favor of Tailwind CSS, but the more components we create, the more classes we have, and the more styles we repeat.

With Tailwind CSS, you will realize that having these utility classes will really help reduce the amount of CSS we ship, as we can reuse the styles using utility classes as much as we’d like.

Think of it as having a single .flex { display: flex; } in the CSS file, instead of having display: flex; 100 times, once for each one of the 100 components in our project that uses that specific style property.

That truly helps reduce our CSS file size.

And this is even more helpful when we have a consistent design system, standardized components, and user interfaces, as Tailwind CSS will try to reuse as many utility classes and CSS statements as possible.

Finally, I know that the HTML doesn’t look as clean as before, but if we think about our users, most of them will not care about how the HTML looks like, and most won’t even look at it.

Remove unused CSS

Tailwind CSS also helps us find and remove unused CSS. Even though Tailwind CSS comes with a handful of utility classes, the compiled, built, or processed CSS will always include only those utility classes you are actually using.

We always have all the utility classes available for usage, but we are safe that any classes we don’t use will not make it to our project’s CSS.

This is harder to achieve and spot when using CSS, as there’s much more code we need to look into and that takes time. Having Tailwind CSS do it automatically is really helpful.

Be Careful

Since Tailwind CSS only compiles the utility classes we actually use, it needs a bit of help in knowing where to check for used classes. And that’s what we configure in the tailwind.config.ts file.

...
  content: [
    './src/components/**/*.{js,ts,jsx,tsx}',
    './src/app/**/*.{js,ts,jsx,tsx}',
    './content/**/*.mdx',
  ],
...

In this case, for example, Tailwind CSS will check for the files with extensions .js, .ts, .jsx and .tsx within the src/components and src/app folders; as well as the files with the .mdx extension within the content folder.

It could happen that if you create another component in a different folder than those, let’s say src/ui, the classes you use there are not compiled. And then you wonder what’s wrong with your code that not all styles are being applied.

It happened to me; I think it’s something easy to miss.

Stick to CSS

If you still prefer to write CSS as you normally would, you can use the @apply directive along with Tailwind CSS and have your CSS compiled as expected.

For example, you can write your CSS as:

.card-one {
  @apply flex flex-row items-center;
}

and that will be compiled to

.card-one {
  display: flex;
  flex-direction: row;
  align-items: center;
}

This is also helpful as we can keep our CSS codebase cleaner and simpler and let the compilation process build the whole CSS we would normally expect.

Developer Experience

It’s common to think that having too many classes in the HTML would complicate the maintainance of our code, make it harder to read, and we would have long lines of code.

Even I dislike that and it stopped me from using Tailwind CSS for a while. But considering the benefits, and finding the right tools, it was more manageable and I ended up liking it.

For example, if we used a tool like react-twc for React projects, we could keep our HTML clean, while still using the Tailwind CSS utility classes.

Here’s an example:

import { twc } from 'react-twc';
 
const Card = twc.div`
  flex
  flex-col
  items-center
  px-6 py-4
`;
 
const Component = () => {
  return <Card>...</Card>;
};

As you can see, we can write our components similar to what we would write with styled-components, but instead of writing CSS properties, we use the Tailwind CSS utility classes.

Which would get compiled and rendered as:

<div class="flex flex-col items-center px-6 py-4">...</div>

That allows us to keep our codebase easy to read and maintain, and let the compiler do the rest.

Conclusion

As with any other tool, framework or library, using Tailwind CSS will have its pros and cons. Those will also depend on the structure and architecture of our projects.

But personally, it certainly has grown on me, and I’m liking it more the more I use it. At the end, Tailwind CSS is, as its name says, still CSS.

And it will keep getting better, faster and simpler to use, which is exciting. I’m looking forward to Tailwind CSS v4.