The TL;DR is: The question to use Tailwind or not, is as easy as do you like it? Does it help and improve your work? If it is; use it, if it's not, don't use it. It really is as easy as that. Know your reasons. Me, personally, I love it. This article describes my past, writing CSS and what problem I encountered that Tailwind mostly solves for me.
I engaged in a brief discussion on Twitter earlier this week. As many times before it was regarding someone who didn't like the utility class approach that Tailwind brings to the table.
I replied with these tweets and that is what I want to write about today
Macke Hansson 🏳️🌈@mackehansson@amcdnl People seem to forget the struggle that was working with css in a large team with different expereince. The ctrl + f, the inheritance, the naming of classes. It was pain.20:12 PM - 20 Mar 2023
Macke Hansson 🏳️🌈@mackehansson@amcdnl Oh and all the unused styles. Working with components(I guess that is what we mostly do today) you write styles once and reuse the component where previous you wrote classes for reuse everywhere. :)20:13 PM - 20 Mar 2023
I want to talk about why I personally love using Tailwind. But to do that, we have to bring it back a couple of years. Back then we had these problems:
Multiple ways to write CSS
In the beginning, it was only CSS (well not in the beginning, but you get the point). We had one way to style our websites. It sure must have been easy and nice, right? Well... The big discussion back then was where to write CSS. Some people said to write it in CSS files whereas others preferred inline CSS. Much like the Tailwind discussions today, it was very opinionated.
But time went on and preprocessor languages became the way to write CSS. Suddenly we had a much more creative way to style our websites. But now you needed to compile your files to CSS. Maybe you really liked to write Stylus and someone else on your team wanted LESS? How to solve those kinds of problems? Oh, and Sass could be written in 2 ways, *.scss and *.sass. I mostly used the *.scss format and still do today.
The code and the file structure
As I said, sass with the *.scss syntax was what I and my team mostly used. Great, we had agreed on how to write styles. Now we arrive at the next problem; Where does the code go? How do we structure the styles? How do we name the classes? Should it be an ID or a class?
This was a shit show out of this world. We had to invent naming conventions just to make styles easier to work with. BEM was my weapon of choice.
Projects often started with the variables file. You added all of those variables that "could be changed someday" in a separate file. Does anyone remember Bootstraps variable file? Impressive stuff. We had the non-functional requirement of Changeability on top of our minds. "This color could perhaps be another color one day". But let's be honest here, how many times did a change of a variable really solve your problems? Search and replace with a proper code inspection was mostly how we changed stuff.
It. Was. Hard.
Unused styles
We didn't have any tree shaking when it came to styles. At least not what I've used. It was all glued together in a styles.scss file with imports everywhere. Imported stylesheets imported other stylesheets.
We had large stylesheet files back then, and it was hard to know what class or id, was in use. So often we shipped unused classes.
Ctrl + F
Now we are up and running. We create the most beautiful websites. Everything is fine. We are adding styles to our HTML and everything is fine. But suddenly, the font weight on our heading is not bold. What happened?
You know what happened here. Inheritance. Somewhere in your codebase, you have some style that takes precedence for the font-weight attribute. But where is it? In a perfect world, you have full control over all the files and knowledge where you have previously added something that could have been the source.
But this is not a perfect world. We have multiple developers on the team with varied skill sets. The solution is to start searching the code for elements, class names, and so on.
On top of that, you have to have full control over the HTML as well. What if the class was in use in another part of the page?
Static web pages and JavaScript frameworks
There is a large shift in how, at least for me, how I work with the web today. I rarely develop big static web pages anymore. I focus mostly on Javascript frameworks.
With static web pages, like a CMS, it makes more sense to have a regular CSS class to be able to reuse all over your website. But when you're working with Javascript frameworks, you mainly work with components that can be reused.
Using Tailwind does exactly the same thing here. We write our utility classes only once (for a specific ui element) in that component and reuse that component.
Let's look at an example of what I mean.
CSS
.card {
width: 200px;
background: #efefef;
}
.card__image {
box-shadow: 1px 1px 5px #000;
}
.card__content {
padding: 16px;
}
.card__title {
margin: 0 0 4px 0;
padding: 0;
}
.card__description {
font-weight: light;
margin-bottom: 8px;
}
.card__actions {
text-align: center;
}
.card__action-button {
background: yellow;
border: none;
padding: 12px 16px;
font-weight: bold;
text-transform: uppercase;
}
This is a very simple ui element, a typical card. First, we write the CSS for it somewhere in a CSS file.
Then some HTML
<div class="card">
<div class="card__image"><img src="https://picsum.photos/200/120" alt="From stockphoto" /></div>
<div class="card__content">
<h3 class="card__title">Car title</h3>
<div class="card__description">
The description for the card goes here.
</div>
<div class="card__actions">
<button class="card__action-button">
Great!
</button>
</div>
</div>
</div>
When working with static HTML, the HTML part is not where you abstract and reuse, but the CSS. This exact HTML could be located in another part of the page. Both use the same CSS classes. Makes sense right?
Now enter the world of JavaScript frameworks. The same HTML, with Tailwind would look like this (inside a Card component):
<div class="w-[200px] bg-gray-100">
<div class="shadow">
<img src="https://picsum.photos/200/120" alt="From stockphoto" />
</div>
<div class="p-4">
<h3 class="m-0 mb-1 p-0">Car title</h3>
<div class="font-light mb-2">The description for the card goes here.</div>
<div class="text-center">
<button class="bg-yellow-400 text-black border-none px-4 py-3 font-bold uppercase">Great!</button>
</div>
</div>
</div>
This component would then be able to be reused all over the place. The styles are written once and contained with the markup. For me, this creates changeability and visibility, both to be able to "see" what the end result will look like in one place.
People who use Tailwind don't know CSS
This argument is just nonsense. I have seen it sometimes. How could you possibly create a design with Tailwind if you don't know what the utility classes even do? You have to know CSS to use Tailwind. Right? I'll even argue that reading the Tailwind documentation makes you better at CSS.
Conclusion
Readability - This is where I see the hesitant user's main complaint. Big complex design elements could have many many classes. This is the question in the first tweet. 20 class names instead of fewer (depending on CSS naming conventions, like BEM with modifiers, it could, with CSS, be like 1 to 3 classes). For me, this is not really a problem with modern code editors that makes code so easy to read. Typically I write the classes once, modify them to my needs and then I don't really care about them. I move on to the next element.
But of course, reading 1-3 classes is easier than 10+. It's not an argument. But for me, it's easily tradeable for the speed(Tailwinds JIT compiles used classes only = smaller CSS files to the user and lack of separate CSS file) and visibility of what I'm building.
But in the end, It's up to you to use what you and your team are comfortable with. If Tailwind does look like a mess and that mess will break or slow you down. Don't use it. That is your reason. But don't try to tell other people that have their own reason for using it to feel bad for using it. I'm sorry if this article makes the expression that I'm all in Tailwind, and people/teams only using CSS bad. That is not at all what I want to be said. That's your reason and that is fantastic.
You do you, and have fun while doing it.
Top comments (2)
You’re not wrong: CSS is hard, and I’m it’s barest form the lack of obvious and standard structures for modularity and reuse can be a nightmare — especially when working in larger teams and big codebase.
But thinking about your front end structures holistically makes a crucial. CSS doesn’t operate in a vacuum. While I appreciate that the code above is just for demonstration, it’s immediately clear that using fewer divs and introducing more semantic markup would go a long way to helping reduce that classname salad. HTML describes structured document content, with roles and hierarchies and relationships. Leveraging this properly is a crucial part of taming the css it is partnered with.
I agree.
One thing I haven't even included in this article is CSS in JS and CSS Modules. Where you can write scoped CSS to your components. That could make some of my points solved as well.
And I'm not really here to promote Tailwind as the best thing since sliced bread, and convert non-believers but to explain why I'm using Tailwind in most of my projects.