I used to be a naysayer of tailwind. However after getting practically forced into it I'm now drinking the koolaid. Yes things like having to duplicate styles using multi cursor is kind of silly, however for the vast majority of the time, having the styles written clearly each time, for me, makes it worth it.
There is also nothing stopping you mixing and matching.
I can't take this article seriously since the recommendation is to use CSS-in-JS. Perhaps the worst CSS related invention ever, easily surpassing tailwind in it's awfulness.
If you go even minimally outside the beaten path, the tailwind CSS declarations can mutate into a frankenstein monster that makes regular CSS look like a friendly, cute koala
I got eye-strain and headaches after taking over maintenance of a tailwind based website where the original developer had left the team. The class declarations are so huge with 15-30 class names in one line that you always forget where you are. Incidentally, also the top-voted discussion: https://github.com/tailwindlabs/tailwindcss/discussions/7763
I see buttons used as an example a lot but buttons are one of the most style heavy elements on many websites and are only a single element so it's not a good comparison imo.
For a lot of pages, you're often only adding maybe 1 to 5 styles to each element to change some flexbox settings, add some margin, set a background color, or change a font. With the traditional CSS approach, you're forced to come up with class names for each element and put the styling into a separate file, which makes iterating on style and layout really laborious compared to Tailwind.
That's a much bigger benefit to focus on rather than looking at how (single element) buttons are styled. It's not like the CSS for styled buttons is less verbose or even pretty either.
Last days I have spent with Tailwind. But honestly, even if I know all abbreviations now :), and it it eye-bleeding syntax, is there something better in the wild? I know that I could use vanilla CSS, but… how many times do you have enough time to build your own CMS when you can install WP… life is short. Most of us are not building a sustainable system that will be here in next 20 years. Life is short. Deliver fast.
I don't understand the point of the rule sets and constant classes? TailwindCSS still obeys the same specificity rules of CSS so instead of `font-medium` on every <a> tag under nav why not just put `font-medium` on the parent <nav> tag?
> Which class comes first in the generated stylesheet is not predictable. Tailwind's recommendation is to, once again, ignore basic coding principles and recommend you duplicate your business logic…
Use tailwind-merge and never worry about this again. No affiliation, just a happy user.
This describes nicely why I don't use it... I read tailwind docs year+ ago and didn't get what's really the point. You use a bundler anyway and so just use css modules...
I can't believe this article made it to the front page. It feels like the author has some personal vendetta and just doesn't care about the facts.
> Tailwind decided to burst on to the scene and become the default styling solution for all modern web development despite taking each and every one of these problems, exacerbating them, and applying them to places that didn't have them before
If Tailwind is so bad and has literally no upsides then how on earth it managed to take the frontend world like a storm? In authors eyes frontend developers have to be either stupid, or ignorant, or both if they decided to choose such a bad solution en masse.
To me (and probably many others) using Tailwind is all about speed and reducing file hopping. If I ever need to adjust style of anything it's always trivial - just locate the component and adjust the classes. Writing new code is so much faster because I don't need to think about what classname to invent for every single html element I would like to style, I don't need to create separate definitions, files etc. for them. For my particular workflow it's a huge win.
> If you misspell one of these plain strings your editor is not going to tell you. You'll just have to find out once you get into the browser. Did you notice that txt-blue is wrong, and it should actually be text-blue? No? Get used to it, you'll make that mistake daily (...)
This is just plain wrong. You can install Tailwind autocomplete, checks or eslint rules in literally any editor/IDE of your choice and you will never have an issue of misspelling the classes. Most solutions will even autocomplete your custom classes defined in your Tailwind config.
I recently started using it for a SPA I'm building and quickly realized, I don't care if it's the worst, or not. It works, and it works well.
The best part? I can just tell AI what I want, and it spits out exactly what I want, even all the goofy framer-motion animations. If something's off, I can tweak it without ever opening a CSS file.
Massive respect to the devs behind tailwind. I don't care what your blog post says, you'll have to pry it from my cold, dead hands.
Tailwind was better for me before AI, and it’s WAY better for me with AI.
Claude can write CSS and HTML together in my templates, without needing to reference back and forth. It’s very, very good at writing tailwind.
Perhaps Tailwind is the worst of all your worlds, but it’s better than Bootstrap and Bulma and all the other stuff I genuinely tried.
I don’t get why people can’t just let Tailwind users be happy. Like, I’m not writing blog posts about how terrible it is to write HTML in JavaScript for React…I just don’t use it. Live and let live!
I'm surprised that the official Tailwind docs recommend putting the `font-medium` class (i.e. `font-weight: medium` in CSS) on every child element of that <nav> and using multi-cursor editing to change them all simultaneously. `font-weight` is inherited, meaning that they could just add it once to the <nav> element.
I dislike Tailwind and don't use it, but I wonder how many papercuts like this come down to just not knowing CSS very well.
As someone who spent 20+ years as a jack-of-all-trades / full-stack developer, specialising in back-end and database skills, this has largely been... confusing.
Before, I couldn't even make plain text work. Totally hopeless, I didn't have the eye for things.
Now though, now I help my kids lay out their homework to be more visually pleasing. It's bizarre.
(caveats: while I can put together a visually pleasing and consistent websites, I'm not saying that design is easy, nor that designers don't have talents way above my own. I view this more like an enthusiastic amateur at the piano rather than having become a concert pianist.)
I know of one other dev who's experienced the same. I'm keen to learn if there are more of us out there.
Is there any project using React that uses something other than Tailwind? It is the default for many projects, especially those that are new.
Aesthetically, it was well deserved. There is a reason why component libraries build on top of Tailwind.
But every time I touch the framework, I miss Bootstrap. Tailwind is an aesthetic masterpiece, but the code quality feels like a regression. BEM, Bootstrap, Material. Different beasts, even jQuery UI, but Tailwind would be something I might consider, not a masterpiece, judging by the code.
Been using Tailwind since starting my job 5 years ago where we have a ton of webapps standardized on Angular+Tailwind, and you may have to hop into a webapp you've never heard of before to fix a bug. Couldn't be happier with how much easier it is to build and maintain compared to traditional CSS.
Many many words I've read trying to convince me why I shouldn't be having a good time using it, yet here I am more productive than ever thanks to it. Less experienced devs are by default funnelled into writing code that's easy to understand, only looking at one file, as opposed to people trying to do cute tricks where styles could be coming from anywhere in the project. It's SO much easier when the styles are on the component I'm looking at and I don't have to cross-reference between files. Plus people sticking to increments of 0.25rem instead of everyone using their own preferred units is huge.
When you work at a big company you can't expect everyone will write nice CSS. But Tailwind plays a huge part in making sure everyone writes something that's much more easier for the next person who has to read it.
i appreciate the OP's take and insight but couldn't agree more with this comment.
> yet here I am more productive than ever thanks to it.
i have first hand experience with most of the css frameworks. heck, even wrote a custom scss one at one point, but eventually there's a simplicity (admittedly to a fault at times) to tailwind that just makes you more productive.
> Plus people sticking to increments of 0.25rem ins
this is another really good point that doesn't come through as much. Tailwind also does a fantastic job of picking the right defaults which 90% of the internet won't do.
from the OP's original piece
>> it demands the developer who installs it set up a config file that lays out all codebase-wide style constants: colors, margin sizes, fonts, border radii, etc.
... or importantly, it sets up a solid set of defaults.
You'd also be more productive and have less unknowns and potentially less decision paralysis if, say, everyone started using excel hooked up to a database instead of writing their own bespoke CRUD app, but alas, those aren't the reasons one asks programmers to program.
- the styling is colocated with the markup
- sensible defaults
- avoids rule hierarchy/inheritance
- minimal JS at runtime
Disadvantages:
- build step and configuration
- dynamic styling complexity
I don't think that's a bad tradeoff. And we're talking about styling on the web, here. So there are no good solutions. But there is a bad solution and it's CSS-in-JS.
I have come to the same conclusion as the OP: people like tailwind not for its API or ergonomics but for its design system.
Tailwind can actually be decent for templating systems and it’s likely why it’s shipped with Phoenix for example.
But for React components, it’s definitely a step back from CSS-in-JS, which gave you style encapsulation out of the box. Not sure what’s up with the knee-jerk reaction against it in the comments. With vanilla-extract (mentioned in the OP) or PandaCSS, there is no runtime at all.
Just components that defined their structure and style, in a readable way, with less abstraction than Tailwind.
I just use tailwind inside components. This problem is because of no components + tailwindcss, not because of tailwind usage alone. Nothing is stopping one from using components that use tailwind.
Say what you want about Tailwind's usefulness, but the author's claim in the section titled "Rule sets" is objectively false. In the Tailwind documentation they mention the @apply directive which allows you to use Tailwind's styles in your primary stylesheet.
In my own project, I moved to Tailwind recently and found @apply to be very useful. I experiment with the inline styles and move them to a CSS class when (and if) needed. Additionally, the Tailwind CLI translates the states like hover: and active: as well. I personally have found it super convenient.
Can't agree that Tailwind is popular because it forces you to setup a centralized config file (although I guess that is nice).
It's because, as ugly as a long line of inline classes can be, it's easy to know exactly what styles are being applied to an element. Especially when there are more than 1 or 2 devs writing styles.
I've been working on a nativewind [1] app for the last year or so, and all these complaints resonate with me, and then some.
It feels like I have to have a mental model of CSS, tailwind, React Native stylesheets and nativewind-specific conventions to actually accomplish anything. It's terrible.
I agree with the author that the only actually good part is having a single, easy-to-use list of global style constants.
I've used Tailwind to style all of my sites. The author acknowledges but IMO doesn't give enough credit to the filters like dark:, lg:, hover:, etc. that let you concisely create very responsive designs.
81 comments
[ 3.6 ms ] story [ 89.9 ms ] threadThere is also nothing stopping you mixing and matching.
Just use CSS modules. Just use CSS modules.
Example: https://www.nikolailehbr.ink/blog/realistic-button-design-cs... shows an "old fashioned", 90's are back-in-vogue, 3d button.
Tailwind CSS for it becomes
I got eye-strain and headaches after taking over maintenance of a tailwind based website where the original developer had left the team. The class declarations are so huge with 15-30 class names in one line that you always forget where you are. Incidentally, also the top-voted discussion: https://github.com/tailwindlabs/tailwindcss/discussions/7763For a lot of pages, you're often only adding maybe 1 to 5 styles to each element to change some flexbox settings, add some margin, set a background color, or change a font. With the traditional CSS approach, you're forced to come up with class names for each element and put the styling into a separate file, which makes iterating on style and layout really laborious compared to Tailwind.
That's a much bigger benefit to focus on rather than looking at how (single element) buttons are styled. It's not like the CSS for styled buttons is less verbose or even pretty either.
In the end its just another library that if you learn it well it will work for you and it has as many downsides as any other library ever used.
By the way the article seems a bit like an advertising for vanilla-extract library.
Use tailwind-merge and never worry about this again. No affiliation, just a happy user.
https://www.npmjs.com/package/tailwind-merge
> Tailwind decided to burst on to the scene and become the default styling solution for all modern web development despite taking each and every one of these problems, exacerbating them, and applying them to places that didn't have them before
If Tailwind is so bad and has literally no upsides then how on earth it managed to take the frontend world like a storm? In authors eyes frontend developers have to be either stupid, or ignorant, or both if they decided to choose such a bad solution en masse.
To me (and probably many others) using Tailwind is all about speed and reducing file hopping. If I ever need to adjust style of anything it's always trivial - just locate the component and adjust the classes. Writing new code is so much faster because I don't need to think about what classname to invent for every single html element I would like to style, I don't need to create separate definitions, files etc. for them. For my particular workflow it's a huge win.
> If you misspell one of these plain strings your editor is not going to tell you. You'll just have to find out once you get into the browser. Did you notice that txt-blue is wrong, and it should actually be text-blue? No? Get used to it, you'll make that mistake daily (...)
This is just plain wrong. You can install Tailwind autocomplete, checks or eslint rules in literally any editor/IDE of your choice and you will never have an issue of misspelling the classes. Most solutions will even autocomplete your custom classes defined in your Tailwind config.
The best part? I can just tell AI what I want, and it spits out exactly what I want, even all the goofy framer-motion animations. If something's off, I can tweak it without ever opening a CSS file.
Massive respect to the devs behind tailwind. I don't care what your blog post says, you'll have to pry it from my cold, dead hands.
Claude can write CSS and HTML together in my templates, without needing to reference back and forth. It’s very, very good at writing tailwind.
Perhaps Tailwind is the worst of all your worlds, but it’s better than Bootstrap and Bulma and all the other stuff I genuinely tried.
I don’t get why people can’t just let Tailwind users be happy. Like, I’m not writing blog posts about how terrible it is to write HTML in JavaScript for React…I just don’t use it. Live and let live!
I dislike Tailwind and don't use it, but I wonder how many papercuts like this come down to just not knowing CSS very well.
I can now design.
As someone who spent 20+ years as a jack-of-all-trades / full-stack developer, specialising in back-end and database skills, this has largely been... confusing.
Before, I couldn't even make plain text work. Totally hopeless, I didn't have the eye for things.
Now though, now I help my kids lay out their homework to be more visually pleasing. It's bizarre.
(caveats: while I can put together a visually pleasing and consistent websites, I'm not saying that design is easy, nor that designers don't have talents way above my own. I view this more like an enthusiastic amateur at the piano rather than having become a concert pianist.)
I know of one other dev who's experienced the same. I'm keen to learn if there are more of us out there.
Is there any project using React that uses something other than Tailwind? It is the default for many projects, especially those that are new.
Aesthetically, it was well deserved. There is a reason why component libraries build on top of Tailwind.
But every time I touch the framework, I miss Bootstrap. Tailwind is an aesthetic masterpiece, but the code quality feels like a regression. BEM, Bootstrap, Material. Different beasts, even jQuery UI, but Tailwind would be something I might consider, not a masterpiece, judging by the code.
Many many words I've read trying to convince me why I shouldn't be having a good time using it, yet here I am more productive than ever thanks to it. Less experienced devs are by default funnelled into writing code that's easy to understand, only looking at one file, as opposed to people trying to do cute tricks where styles could be coming from anywhere in the project. It's SO much easier when the styles are on the component I'm looking at and I don't have to cross-reference between files. Plus people sticking to increments of 0.25rem instead of everyone using their own preferred units is huge.
When you work at a big company you can't expect everyone will write nice CSS. But Tailwind plays a huge part in making sure everyone writes something that's much more easier for the next person who has to read it.
> yet here I am more productive than ever thanks to it. i have first hand experience with most of the css frameworks. heck, even wrote a custom scss one at one point, but eventually there's a simplicity (admittedly to a fault at times) to tailwind that just makes you more productive.
> Plus people sticking to increments of 0.25rem ins this is another really good point that doesn't come through as much. Tailwind also does a fantastic job of picking the right defaults which 90% of the internet won't do.
from the OP's original piece
>> it demands the developer who installs it set up a config file that lays out all codebase-wide style constants: colors, margin sizes, fonts, border radii, etc.
... or importantly, it sets up a solid set of defaults.
- the styling is colocated with the markup - sensible defaults - avoids rule hierarchy/inheritance - minimal JS at runtime
Disadvantages:
- build step and configuration - dynamic styling complexity
I don't think that's a bad tradeoff. And we're talking about styling on the web, here. So there are no good solutions. But there is a bad solution and it's CSS-in-JS.
Tailwind can actually be decent for templating systems and it’s likely why it’s shipped with Phoenix for example.
But for React components, it’s definitely a step back from CSS-in-JS, which gave you style encapsulation out of the box. Not sure what’s up with the knee-jerk reaction against it in the comments. With vanilla-extract (mentioned in the OP) or PandaCSS, there is no runtime at all.
Just components that defined their structure and style, in a readable way, with less abstraction than Tailwind.
Here is the portion of the documentation which talks about this: https://tailwindcss.com/docs/functions-and-directives#apply-...
In my own project, I moved to Tailwind recently and found @apply to be very useful. I experiment with the inline styles and move them to a CSS class when (and if) needed. Additionally, the Tailwind CLI translates the states like hover: and active: as well. I personally have found it super convenient.
It's because, as ugly as a long line of inline classes can be, it's easy to know exactly what styles are being applied to an element. Especially when there are more than 1 or 2 devs writing styles.
Unless a project has really messed up, it is trivial to see what styles are being applied to any element.
It feels like I have to have a mental model of CSS, tailwind, React Native stylesheets and nativewind-specific conventions to actually accomplish anything. It's terrible.
I agree with the author that the only actually good part is having a single, easy-to-use list of global style constants.
Everything else sucks.
[1] https://www.nativewind.dev/
> There are only two kinds of languages: the ones people complain about and the ones nobody uses.
So yeah. Amen.
The latest Tailwind version lets you even style with data: attributes: https://tailwindcss.com/blog/tailwindcss-v3-2#data-attribute....
Using Tailwind I get a world-class CSS expert (Adam Wathan) helping me out. The actual raw CSS doesn't go nearly as far in the DevX direction.