11 ms·
CSS's problems are Tailwind's problems
- jackdh 1y agoI 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.
- pier25 1y ago> There is also nothing stopping you mixing and matching. Yes, common sense. Having multiple approaches to solve the same thing tends to be a bad idea.
- hugeBirb 1y agoThis is an extremely limiting view. They are both CSS at the end of the day. If extracting the complicated inline TailwindCSS class to its own vanilla CSS class makes sense for readability then what's the harm? You could also just define your own variables. Tailwind gives you full control to do this.
- pier25 1y agoThe harm will be in a complicated project where you might have to figure out where some styles are coming from.
- jackdh 1y agoMy point is that there is no one CSS library to rule them all and likely never will be. The closest to that is going back to pure raw CSS which I highly doubt people will do. And yes while it's obviously not ideal to have a hundred competing libraries in your code, you can create what works for you / your team.
- pier25 1y ago> The closest to that is going back to pure raw CSS which I highly doubt people will do. Huh? Tons of people write vanilla CSS which is getting better every year.
- const_cast 1y agoVery very few people, in practice, write vanilla CSS. They use libraries and frameworks often, like Bootstrap. Sure, that might be "vanilla CSS", but you didn't write it, presumably because you didn't want to. Look, after a certain point we have to call a spade a spade and acknowledge that CSS is just too cumbersome, too awkward, and too complicated for most developers and companies. How much CSS do you see that seems to be read-only? People just... tack on to the end of the style sheet, right? The promise of re-usability is great, but is it actually happening? IME, no.
- pier25 1y ago> Very very few people, in practice, write vanilla CSS. That's not what I've seen. Most frontend developers I know usually write CSS (or SCSS previously). > CSS is just too cumbersome, too awkward, and too complicated for most developers and companies. Really? I disagree but are you arguing TW solves any of that?
- varbhat 1y ago...then goes on to promote "CSS-in-JS"
- Lammy 1y agoEverything old is new again: https://www.w3.org/submissions/1996/1/WD-jsss-960822 https://www.w3.org/submissions/1996/1/WD-jsss-960822
- lenkite 1y agoIf 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 Example: https://www.nikolailehbr.ink/blog/realistic-button-design-css 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 <button class="relative cursor-pointer overflow-hidden rounded-md border border-neutral-950 bg-neutral-900 px-3 py-1.5 text-neutral-100 shadow-md inset-shadow-2xs inset-shadow-neutral-600 transition-all before:absolute before:inset-0 before:bg-linear-to-b before:from-white/20 before:to-transparent hover:bg-neutral-800 active:bg-neutral-950 active:shadow-none active:inset-shadow-neutral-800"> After </button> 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 https://github.com/tailwindlabs/tailwindcss/discussions/7763
- micromacrofoot 1y agoI can't believe people find even half of this acceptable, do they never use a browser inspector in their work?
- aidos 1y agoI do, and it’s great having the styles right there and hackable.
- recursive 1y agoHow can styles ever not be hackable? Inline styles always take precedence. What can ever stop you from slapping in more inline styles?
- ericwood 1y agoTo be fair, this is the case with any styling approach; if the style is applied to the element, it's there for you to toy with in the inspector.
- dminik 1y agoI 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. Just use CSS modules. Just use CSS modules.
- coltonv 1y agoI'd really appreciate reading the whole article before commenting like this. I point out the problems with CSS-in-JS and do not wholly endorse it, and I do recommend using simple CSS as a solid solution for many people.
- dminik 1y agoI reread the conclusion. I apologize for jumping to conclusions so fast but ... You specify like 4 approaches: 1. Tailwind - apparently awful 2. Regular stylesheets - also not good 3. Inline Styles - some flaws 4. CSS-in-JS - minimal flaws when using vanilla-extract Reading through the article, my first thought was that you really like vanilla-extract. When I got to the conclusion section, and the first line is "I like vanilla-extract" I wrote the comment. Nonetheless, even after finishing that section, without knowing better, I would assume that vanilla-extract is what I should be looking at further.
- jakelazaroff 1y agovanilla-extract has zero runtime impact, right? I personally prefer using CSS modules (by a lot) but I don't see a huge difference between the two.
- coltonv 1y agoI do think you should look at it further! It's a great library, though I can see why people won't like it for the reasons I mentioned in the article (i.e. having to build and enforce your own constants system). If you are going to use something like Tailwind, you're already okay with putting styles in Javascript and adding a bundler plugin, the two main "leaps" required to use something like vanilla-extract. Since the style sheets are extracted into CSS and do not contribute to JS bundle size, I'm not sure visceral CSS-in-JS reaction is justified when it comes to vanilla-extract. Tailwind is still basically CSS-in-JS, but more of a hybrid of CSS-in-JS and CSS-in-JSON. Could you elaborate on your frustrations with CSS-in-JS as it pertains to vanilla-extract, the one CSS-in-JS library I recommend?
- blain 1y agoI'm sure many still like Tailwind but I never liked it, maybe because I worked with pure CSS or SCSS for many years before it. 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.
- hugeBirb 1y agoI 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?
- deleted 1y ago[deleted]
- eithed 1y agoI'd like to hear authors opinions about BEM
- ARandomerDude 1y ago> 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. https://www.npmjs.com/package/tailwind-merge https://www.npmjs.com/package/tailwind-merge
- throwaway290 1y agoThis 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...
- M4v3R 1y agoI 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.
- coltonv 1y ago> 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. Please read the entire article before commenting. I have an entire section on this. I don't think frontend devs are idiots and never said they were. Tailwind offers global constants configuration out of the box, which is the most important problem people are looking to solve, which is why I think such a flawed library has so much success. > 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. Part of my point is that this already exists with inline styles. In react for example you can set up some plain JS constants and import them to do inline styles. And you get the benefits of type checking and other JS features. That's not a perfect solution either, and it's not one I'd endorse past hobby projects, but my point is that Tailwind just takes an existing pattern and makes it worse. > 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. These are okay but trip over themselves and cause issues if you have any plain CSS class usage, which is necessary in certain situations in my experience.
- jwblackwell 1y agoIt works much better with AI though, which is really all that matters at this point
- recursive 1y agoThat's crazy. Coding without AI doesn't even matter anymore? I could understand saying it's not preferred by some. Or that it's sub-optimal. Or old-fashioned. But it doesn't matter at all?
- movedx01 1y agoIs that true though? Every time i tried to get Sonnet to write out any actually complicated layout/component, I ended up with a novel of classNames with a ton of duplication and useless additions. Those are very hard to spot inside a soup of tailwind classes, whereas I can see them immediately in a nicely laid out stylesheet. This happened extremely often when I tried to iterate with Cursor/CC on the given design, instead of giving up immediately after it failed to one-shot it.
- latchkey 1y agoI 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.
- iambateman 1y agoTailwind 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!
- throwawaymaths 1y agoyeah I was going to say this. AI is incredibly good at writing tailwind. Part of it is probably exactly the colocation issue. Context windows are precious.
- hombre_fatal 1y agoAlso, Tailwind is included in Claude's artifact/preview system and Claude is prompted to use it by default. Hard to beat that compared to "oops, pls implement it in Bootstrap" and then copying the output to JSFiddle with Bootstrap loaded just to see it. :( I don't use Tailwind but what usually happens is that it creates a great Tailwind mockup that I'm happy with, and then I tell it to port it to Bootstrap (which involves a mix of Bootstrap classes and custom CSS) and it always looks worse, heh. So Tailwind + LLM support is pretty big advantage.
- nicce 1y agoAI was incredibly bad when Tailwind v4.0 was released. All the models trying force me to use the config file I did not want to and so on, every time.
- iambateman 1y agoUse Context7 or another documentation MCP server for that. Then you can say "Tailwind4 has major changes, please review using context7" and it'll sort out some of that.
- 1y ago
- jakelazaroff 1y agoI'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.
- uonr 1y agoI use tailwind because I'm fed up with inheritance.
- mootothemax 1y agoTailwind is magical to me for one reason alone: 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.
- kccqzy 1y agoA decade ago Bootstrap helped a generation of programmers who don't know how to design make pleasantly looking websites. I fail to see how Tailwind is better suited to that task than Bootstrap.
- mootothemax 1y agoyeah that's not what I'm saying
- 9dev 1y agoWith bootstrap, there was a fixed set of components to pick from. For a lot of things, there were no suitable components, so people used those that they had for everything else, kind of like designing furniture in Minecraft with blocks. This makes bootstrap interfaces bland and overly similar, in a way that Tailwind doesn’t: its design system is fundamentally based around design tokens arranged in sensible steps, not full components. That allows for a lot more flexibility and stylistic control.
- dontlikeyoueith 1y agoBecause it's newer and trendy and that's important for programmers learning their first tool that solves an old problem. Whether it should be important is another question, but it's a simple fact that it is.
- _the_inflator 1y agoI am very thankful for these insights. 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.
- hbn 1y agoBeen 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.
- vijivishali 1y agoI echo this. For all the supposedly bad things it is, Tailwind provides a level of common denominator in a big team still making sure the CSS at the basic level is nice.
- yowzadave 1y agoIt doesn't even require a big team to be useful—I won't remember how I organized a set of styles a few months from now, and having Tailwind require a minimal set of constraints, and keeping the styles easily editable in the place you use them makes things more maintainable over time.
- sorcercode 1y agoi 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.
- theSherwood 1y agoThe advantages of Tailwind are: - 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.
- freddydumont 1y agoI 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.
- mejutoco 1y agoI 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.
- directmusic 1y agoSay 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. Here is the portion of the documentation which talks about this: https://tailwindcss.com/docs/functions-and-directives#apply-directive 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.
- ahuth 1y agoCan'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.
- roguecoder 1y ago... do people not know about browser developer tools? Unless a project has really messed up, it is trivial to see what styles are being applied to any element.
- DangitBobby 1y agoAh yes, so much easier to poke through the styles in the dev tools than to just put your eyeballs on the css class in the file.
- ipsento606 1y agoI'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. Everything else sucks. [1] https://www.nativewind.dev/ https://www.nativewind.dev/
- rc_kas 1y agoI love a good bit of dissent. Also I love Tailwind. > There are only two kinds of languages: the ones people complain about and the ones nobody uses. So yeah. Amen.
- jasonthorsness 1y agoI'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. The latest Tailwind version lets you even style with data: attributes: https://tailwindcss.com/blog/tailwindcss-v3-2#data-attribute-variants 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.
- CreepGin 1y agoAs someone who maintains multiple JS libs and provides support on Discord, the #1 reason I default to using TW is because it lets me drop code snippets in chat without lugging around an extra CSS file or walls of inline styles, keeping everything compact and easy to read (tons of vertical space saved). Example: https://onejs.com/docs/web/tailwind#quick-example https://onejs.com/docs/web/tailwind#quick-example Without TW, that snippet may need to take 3x more lines. --- My major issue with TW at the moment is that I use TW in a non-browser environment (Unity), so TW3 is fine since I can tweak everything with JavaScript. TW4 shifts everything to CSS, gives zero workarounds, and my setup crumbles.
- moron4hire 1y agoIn 5 years, Tailwind will be old and ugly and there will be a new hotness that everyone will crow "solves" styling, and everyone will argue about it and burn $$$ on reimplementing projects with it. And in 5 years, I'll still be doing CSS, not slowed down one bit. My old projects will still work. My new projects will get out the door on time and budget. And the new front-end devs who met me during a back-end discussion meeting will continue to assume I don't know anything about front- end and will still pressure me to switch. And my team will still be called in to clean up after them when they fail to deliver.
- maxmaio 1y agoI use tailwind on all of my projects now and like it. I've used a lot of the css fads of the last decade (css in js was the worst which ironically is what the author recommends) and tailwind is the most ergonomic for me -and apparently most web devs considering how popular it is. "Did you really say bundler?" If you dont use a bundler this is a fair point. But I'm confident you do use one so adding tailwind is ~3 lines of code.
- coltonv 1y agoI should have phrased this better. My point isn't to say that a bundler is a bad idea (I of course use bundlers on most projects at this point). My point is to say that a library that feels like it does so little still requires a bundler feels wrong.
- wuz 1y agoTailwind has taken the world by storm because it let's engineers completely ignore actually learning the technology that powers the web. That doesn't make it good - and it isn't. It's a bloated mess with tons of random technology surrounding the ecosystem in an attempt to make it usable. Tailwind literally only becomes usable for large scale applications once you have combined base tailwind, postcss, a number of tailwind plugins, custom themes, tailwind-variants, tailwind-merge, clsx/classnames, some custom written typescript typing tools, and a number of editor and linter plugins. People here saying "It works well with AI" is such a wild take for so many reasons, not least of which is just straight up admitting that you don't mind your code being unreadable garbage because you aren't reading it anyway. The `@apply` syntax glazing here is wild too - you're literally just writing CSS at that point. Just use vanilla CSS. Like that is all this is: ```css .select2-dropdown { @apply rounded-b-lg shadow-md; } .select2-search { @apply rounded border border-gray-300; } .select2-results__group { @apply text-lg font-bold text-gray-900; } ``` The only "good" thing about tailwind is that right now the rest of the ecosystem is woefully lacking for a number of reasons and tailwind has the benefit of being used by a ton of random projects so you can find tools and references to make it better. But it's not good.
- roguecoder 1y agoWeb technologies succeed when they let people not have to understand things. React is the same as tailwind: it captures the box model experts already used to reason about web pages and made it literal. As long as the job of "web developer" is about assembly-line delivery of features, it will continue to be strategic to choose tools that are worse for experts and better for amateurs.
- dcre 1y agoThe idea that Tailwind prevents you from learning CSS has always been very silly because Tailwind is CSS. You cannot learn Tailwind without learning a lot of CSS. The Tailwind docs are the most concise and practical CSS docs around.
- anonzzzies 1y ago[dead]
- 827a 1y agoMy complaint with tailwind is that it doesn't do a good job of working well with components. E.g. if I have a component that wants to set a default background color for a button, but makes it customizable, I might think to do something like this? export function MyButton({ className }) { return <button className={clsx("bg-red-500", className)} /> } <MyButton className="bg-green-500" /> But that doesn't really work, because ultimately we've just provided both the bg-red-500 and bg-green-500 classes, and we're leaving it up to the precedence rules in the browser CSS engine (which I'm sure are consistent, but that feels like a no thanks from me) So instead I end up doing something like: export function MyButton({ bg = "bg-red-500" }) { return <button className={bg} /> } <MyButton className="bg-green-500" /> But that also feels unsatisfying, because while that prop is named 'bg' you could literally provide any tailwind class you want through it; there's no way to constrain it to only allow tailwind classes which are functionally interchangeable with bg-red-500. Anyone else run into this and have a nicer solution?
- jakelazaroff 1y agoYeah, use CSS variables. I wrote a TIL on doing this exact thing (customizing a button's background color from outside) with vanilla CSS: https://til.jakelazaroff.com/css/dynamically-change-styles-from-html-or-jsx/ https://til.jakelazaroff.com/css/dynamically-change-styles-f... In Tailwind you could probably replicate this with custom variants or whatever they're called.
- phatskat 1y agoI don’t know that this exactly addresses your issue, in fact I don’t think it does, but when I have a case like this there’s two approaches: The first is that my button will have variants, eg “primary, secondary, danger”. Those are a prop, the prop only accepts those values, and the value determines the classes applied ``` <button :class=“{ ‘bg-blue’: variant === ‘primary’, ‘bg-amber’: variant === ‘secondary’, ‘bg-red’: variant === ‘danger’, > ``` You could also have those variants just make a class=“variant-<value>” class and then use scoped styles to apply the proper classes - I’ve personally moved away from scoped styles in the last year. Alternatively, such as in your case, I’d honestly lean towards !important: ``` <MyButton className=“!bg-green-500”> ``` And I know I know, !important bad!, and at least with Tailwind it’s obviously clear when someone has used !important. There’s no need to dig into the style files to track down the rule only to find someone sprinkled !importants everywhere.
- wwweston 1y agoThis is a novel take that I think genuinely adds something to tired tailwind discourse: > I think the most important factor in Tailwind's success is that it does one thing very correctly: 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. Writing individual styles that do not use a pre-configured constant from the config file is clunky in Tailwind. This is a good thing, an unironic win for Tailwind. More than anything else, this is what a large codebase with multiple frontend devs needs: a rigid set of global constants that everyone is strongly incentivized to use. I’m still considering its merits, but it at least goes beyond the “How I learned to stop worrying and embrace tailwind’s standardized soup” vs “I can’t stand this, it goes against every organizing principle I’ve found useful” familiar dichotomy.
- roguecoder 1y agoIt is also a great example of where worse is better, when it leads people to doing work they always needed to do.
- treyd 1y agoBut this isn't unique or new with Tailwind. SCSS and that family of tools had this 10 years ago.
- wwweston 1y agoI think the SCSS and SASS implementations I used 5-10 years back had the capability but didn’t require any set variables, and I think one point of the argument is that this has more benefits than you’d think.
- hombre_fatal 1y agoSince Tailwind looks obviously bad on first pass with all the class spam, I'm more curious to see someone steelman Tailwind. I have some ideas, like how the dead code elimination + granular but consistent classes lets you build novel components that are still consistent with your UI which might be essential for making a 3rd party component library work. I've been using Bootstrap since it came out 15 years ago but it never developed a 3rd party component library. I assume because it doesn't have the same sort granular building blocks for building novel components. Then again there are also component libraries like https://ui.mantine.dev/ https://ui.mantine.dev/ that don't use Tailwind. I sadly never really looked into these modern options since when I want to build something, the last thing I want to do is dick around with a whole new UI solution vs Bootstrap muscle memory.
- moritzwarhier 1y agoI think the best argument for Tailwind still is the blog post that the creator wrote to promote the idea (it was before the first alpha release iirc): https://adamwathan.me/css-utility-classes-and-separation-of-concerns/ https://adamwathan.me/css-utility-classes-and-separation-of-... Everything is a tradeoff. I don't miss Tailwind in my day job, but I would certainly if I had to work on the type of project where I last successfully used it.
- timr 1y ago> I've been using Bootstrap since it came out 15 years ago but it never developed a 3rd party component library. I assume because it doesn't have the same sort granular building blocks for building novel components. Except, it does now. Presumably because of the popularity of Tailwind, Bootstrap has all of these inline utility classes, and LLMs absolutely love to spam them across your code. It’s really annoying when you have a stylesheet with a few dozen well-scoped lines, and the LLM just starts bashing inline styles everywhere.
- hombre_fatal 1y agoTrue, though Bootstrap's utility classes are extremely limited compared to Tailwind's classes. And they aren't very foundational. More like a fast way to bolt on tweaks.
- jollyllama 1y agoYeah, but, Tailwind has a standalone compiler that lets me avoid NPM, so I'll still use it every time.
- zhengkyl 1y agoIn regards to developer experience, UnoCSS https://unocss.dev/ https://unocss.dev/ has a better implementation of tailwind for the JS ecosystem. It uses the build step so you can write code like hover:(bg-red-500 text-white font-bold) and it compiles to separate classes. It's very configurable for better or worse, and the VSCode extension is better too.
- zero_shift 1y agoI'm a bit of a luddite with CSS. I learned BEM about five years ago and I've more or less always stuck to component scoped CSS files. Sometimes I use CSS-in-JS if a component system demands it, like Material. I don't mind it as much as others do, I like that there's no CSS concatenation weirdness. But otherwise I feel quite happy with a component file and a style file. For Tailwind fans (or even detractors), what's the main benefit I'm missing?
- omnimus 1y agoIn my case of many small long running projects with multiple people… 1. Speed - you can get stuff done quickly without making problems globally. 2. Self documenting - both in visibility of html but also because of system/config it forces. People understand to use only values (spacing, sizes, colors) in the config or document that they had to add something and why. 3. CSS specificity is not issue. 4. Performance - straight simple classes are very performant. Complex selectors and pseudo classes can be surprisingly taxing without people realizing it. Thats how functional css started btw
- zero_shift 1y ago(not sure why I said "five years ago" - I learned BEM back in 2014)
- jrub 1y agoI get the frustration, but I think Tailwind’s biggest win is what it trades: structure and locality instead of style purity. Traditional CSS gives you basically nothing in terms of hierarchy or organization. You end up writing long, awkward selectors like .checkout .summary .item-title .price, which still aren’t that readable. And if you’re tracking down why there’s 4px of padding instead of 6, good luck figuring out which of the five CSS files is messing with it. Tailwind flips that. Putting the styles right on the element means the structure is obvious. You don't have to context-switch or go hunting through a bunch of files just to see what’s going on. It’s all right there. Yeah, sometimes it gets verbose. Especially when you’ve got a div with 20+ classes. But when that happens, you’ve probably got something reusable anyway. And Tailwind actually shows you that. If you copy and paste the same set of classes to another element, you’ve just signaled that you’re repeating yourself. That’s your cue: take the extra 60 seconds and extract it into a component or class. With vanilla CSS, that signal is way more opaque. People end up not writing composable styles at all. Instead, they name every div, then name every element inside the div, just to avoid writing selectors like .component div h1 span—which is even harder to reason about than .component .title .icon. And honestly, writing Tailwind is just faster. Typing px-4 is way easier than padding: 0 4px;, and I don’t have to stress over naming a class that won’t collide with anything else. Naming things sucks. Tailwind helps you skip that whole mess and just build. Another bonus: Tailwind is easy to delete. You don't get tangled side effects or some random override breaking stuff in weird ways. Kill a class and you know exactly what changed because it’s right there in the markup.
- blast 1y ago"Tailwind is the Worst of All Worlds" "it does one thing very correctly" ... so there's at least one worse world then
- exiguus 1y agoI agree. You can also use Tailwind in CSS modules or in SASS, or create your own CSS helper classes. There are many tools available that merge and allow conditional CSS classes. Basically, you can use the same tools as in vanilla CSS to organize your code. If you use any component library, most of your CSS should be within the component library, not in your application. Components can have variants, such as primary and secondary buttons, for example. This adheres to the DRY principle. Your application can also have reusable components, which helps minimize the use of CSS and HTML. This adheres also to DRY. You can also build your own Component-Library. You can apply the same programming principles and organizational patterns to HTML and CSS as you would to any other code. This becomes much easier if you separate the view from the rest of the application.
- tptacek 1y agoEarly in the article, the claims is made that Tailwind has "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". Later, the case is made that this happened because Tailwind offers a single configuration file. How true does this sound? How little credit does it give to the huge number of front-end teams that have adopted it?
- aeonfr 1y agoThe whole block about performance is just… not correct? Tailwind, and atomic CSS libraries, scale better, not worse! Look at how facebook leverages atomic CSS to reduce CSS by 80% https://devmohit.medium.com/facebook-generating-atomic-css-to-reduce-homepage-css-by-80-percent-what-is-atomic-css-f4c76722a597 https://devmohit.medium.com/facebook-generating-atomic-css-t... Even if we consider small codebases, the examples OP shows seem to ignore Zip compression and how it works, which is ironic for someone who is arguing about performance as if it could be measured only in bundle size…
- gizzlon 1y agoI would not expect compression to help performance in the browser?? Bytes transferred, sure, but that's not what OP is talking about
- bonthron 1y agoI like utility classes, but not tailwind. It's predecessor, Tachyons is small, simple, and all I've ever needed. https://github.com/tachyons-css/tachyons/ https://github.com/tachyons-css/tachyons/
- etchalon 1y agoTailwind's problems can be summed up as "There are a lot of people who don't want to learn CSS, and even more who don't want to learn how to maintain it well."
- phatskat 1y agoI’ve been doing web development for around 20-ish years and done plenty of CSS, lots of organizing files, SCSS, and been on large teams with great design systems, and I’ll take Tailwind any day.
- etchalon 1y agoI find it absolutely weird when someone knows CSS and finds Tailwind preferable. It's like finding out a carpenter loves Ikea.
- robin_reala 1y agoHell, I work for IKEA and I still prefer CSS.
- jmuguy 1y agoIt would be helpful to link to the Tailwind section about duplication https://tailwindcss.com/docs/styling-with-utility-classes#using-multi-cursor-editing https://tailwindcss.com/docs/styling-with-utility-classes#us... As someone that used Tailwind for years at this point, you're right about why its so popular. To me it was just a better version of Bootstrap. Its defaults look nice, its color choices are nice. I would also mention that their docs are top notch and Tailwind UI makes it really to just copy and paste some decent looking basic components. As someone that spends most of their time on backend, I just don't really care that much about CSS. I think that's something that's lost with all the bikeshedding about it to me its similar to higher level language vs something closer to the metal. So when people say "just use CSS" its like someone telling me I should write in C rather than Ruby. No thanks, I don't have to - why should I?
- darepublic 1y agoSetting up the tooling around tailwind is more a pita than vanilla CSS imo. If you are using tailwind just for the nice default styles there are already myriad simpler solutions for that. Comparing the use of vanilla CSS to.. writing in C, I don't get it.
- darepublic 1y agoJust goes to show how many noxious weeds grow in the JavaScript garden. And how they have fanatical adherents whose careers are based on trying to get square wheels to roll. Even without AI this was a bubble waiting to burst
- shmolyneaux 1y agoI don't really do much in the web ecosystem, but I'm surprised how many people have a strong dislike for tailwind. I've had a lot of success using it. I'm really suspicious about the performance concerns brought up in the article. Does the author think that long strings are really such a huge issue for the size of the JS bundle or processing time in the browser? From my experience it's much easier to refactor the styling of a page using tailwind than modifying CSS. Needing to name a bunch of classes in HTML to reference in CSS adds a lot of obfuscation and it can be difficult to come up with those names. When the structure of the HTML changes the CSS inevitably breaks. I find that it's easier to keep the styling working when using tailwind. I think that the value of keeping styling DRY is overblown. The author gives an example of some tabs that all use `font-medium` and how bad it is to need to modify all the uses at once. This seems like a non-issue to me. If you see the web page you would immediately see the issue if you forgot to change anything. Alternatively, you can still use `@apply` and classes if you don't want to repeat yourself. Even further you probably want to create reusable components anyways. Tailwind is very easy to debug. I've never had an issue understanding why styling wasn't working when using it. In CSS I found that getting the styling right was a constant struggle. The author mentions the issue of setting the text to red and blue in the same class attribute. He compared it to using `!important` in CSS, which is so far from the truth. You can immediately see the issue if the color isn't what you want. Inspecting the element in the browser would immediately show you that you set the text to multiple colors. Tailwind solves a bunch of problems for me. Components are more self-contained. The class names are much easier to remember that the underlying CSS. The set of attributes you can use are focused to a small set of usable features. Animations are much easier. Responsive designs are easier to create. Flexbox (the most useful part of CSS) is easier to use. I work with a number of older developers (very smart folks that just haven't done web development) and I have a much much easier time getting them proficient with tailwind than CSS. I strongly believe that tailwind is better for individuals, better for teams, better for beginners, easier to set up, and easier to maintain. If you're already a CSS expert or if you have an existing design system I can imagine that you wouldn't want to pick up tailwind. But for most websites and most teams I expect tailwind is a great option.
- phatskat 1y ago> Inspecting the element in the browser would immediately show you that you set the text to multiple colors. Even better, the Tailwind LSP will show a diagnostic warning if two classes affect the same property, eg “The text-blue and text-red classes affect the same property” or something like that.
- vehemenz 1y ago> Tailwind does nothing to reduce the mental load on your developers to understand, read, and write in your codebase. In fact it does the opposite. Your developers are not spared the hassle of learning CSS by instead learning tailwind's abstractions. Developers have to understand not just that background-color is the CSS key to set a background color, but they also must understand that classes prefixed with bg- mean background color. Every feature of CSS, such as media and container queries, will need to be learned twice, CSS style and Tailwind style. Just wrong. The whole point of 1:1 style:class mappings is that you don't have hidden structures relating the DOM to your stylesheet's class abstractions. If you're going to talk overhead, talk about all the abstractions and hidden structures you have to learn in a codebase written in the "correct" way to do CSS. It's just incomparable. Tailwind's class names are trivial to learn for anyone that already understands CSS. It's minimal overhead compared to learning CSS. "Learning it twice" is completely inaccurate.
- Francute 1y agoBut you can achieve the same thing (1:1 style:class mappings without hidden structures) using other libraries, like the ones mentioned here; styled components and vanilla-extract. You can even achieve that natively with web components. So, I truly agree with this blog post, and I even wanted to rant the same things showing that you should not compare tailwind against classic CSS stylesheets from 2010, but against how different solutions looks like using different tools the community seems to have thrown away or forgot. And I know is not relevant to your comment, but I will add that "but you will have to maintain more files instead of just a single HTML file" is not a valid argument for me. If that were something good, then just put everything into a single giant server.<your_language> file + separated lib dependencies. We want maintainable easy to follow and understand files. Having a clean html with no cluttering + intuitive CSS styles being applied where we expect them and looking exactly as we expect them while reading the html, is the big win for me, and Tailwind definitely does a step back on this, especially when other tools can achieve that. (Lastly, we have set multiple projects with different tools, and the amount of "wtf"s we've seen with tailwind is way higher than just styled components to give one example) I agree that the only good thing Tailwind achieves, is setting a default convention on having a single config file where you can set everything that you will need on every design across all your html files
- p4bl0 1y agoI never liked Tailwind. The point of CSS was to separate content and presentation. Tailwind not only goes backward on that but does it a lot worse than HTML did before, because the presentation not only is mixed with HTML but is also just a long random string rather than structured into HTML attributes. It's just like CSS using only style="" attributes, only with a different, almost proprietary syntax that you have to learn on addition to actual web standards.
- gherkinnn 1y agoOh why can't this idea go away. That might or might not have been the idea, but it does not scale beyond a text document. It so does not. If it did, we wouldn't have 15 years of Sass and Less and Stylus and CSS Modules and Styled Components and BEM and SMACSS and Tailwind. I have been through it all and Tailwind is the easy winner both for productivity and maintenance over 5 years. I sort my cutlery by knife/fork/spoon, not handles and implements.
- jumploops 1y agoI hated Tailwind when I first used it. > (Tailwind) demands the developer who installs it set up a config file that lays out all codebase-wide style constants > I believe this is where Tailwind has succeeded and other libraries have struggled. This isn't why Tailwind has "succeeded," in my experience. Until Sonnet 3.5, LLMs were pretty awful at creating any sort of UI with normal CSS, but were partially usable with Tailwind due to the colocation of styles with elements. Even with Sonnet 3.5+, Tailwind seems to perform better than other CSS solutions (though the gap is getting smaller with each new model release). The author calls this out, but with the wrong conclusion: > Lastly, Tailwind has also been buoyed by being by being the default styling that just about any LLM or vibe coding tool will produce [..] Plenty of developers started using jQuery because the first StackOverflow result in their search explained how to solve that problem with jQuery. Maybe the reason jQuery was so popular wasn't due to recommendations on StackOverflow, but it's prevalence on StackOverflow was due how easy it was to adopt? Tailwind has "succeeded" for the same reasons it's excelled with LLMs: - colocation of styles with elements - decent defaults (i.e. bg-sky-600, font-bold) - simple solutions to common challenges: - responsive design (lg:flex-row) - dark mode (dark:text-white) - conditional state (hover:bg-red-600 focus:outline-violet-500 Obviously, Tailwind, just like other CSS-in-JS solutions has it's problems/limits, but it's easy enough to fall back to normal CSS for these one-off solutions. I now use Tailwind everyday, and it's no longer the worst thing in the world.
- phatskat 1y agoI think I’ll take another jab at this part > Lastly, Tailwind has also been buoyed by being by being the default styling that just about any LLM or vibe coding tool will produce Tailwind, afaik, was doing just fine without LLMs “buoying” it - I’ve been using it for several years now and have been pretty pro-Tailwind since getting the hang of it, and it was rare to move to a new project that wasn’t already using it. The idea that LLMs are making it more popular is interesting but I don’t think Tailwind is a ship that would have sunk without them, on the contrary I think it’s been a solid choice for a while now for a lot of good reasons.
- huksley 1y agoTailwind is great for layouts. For configurable components, not sure. I also dislike the mess with colors. Cursor IDE uses those navy-100, red-100 absolute colors, instead of using text-destructive, etc (for light/dark mode support), and it is also difficult to tell it does otherwise. So I need to fix this manually, and it is quite time-consuming.
- cadamsdotcom 1y agoBreaking things into components eliminates the repetition AND eliminates separate CSS. Using Tailwind without components is the worst of all the worlds. You could do it though, just start off your journey a CSS file like this: ``` .btn-confirm { @apply min-w-[200px] block bg-green; // plus many more, probably } ``` But that sucks because now you have a separate CSS file outside your component. Where will you put it in your codebase? Will it grow other random styles over time? You’re asking for a mess. Better to do: ``` export default const ConfirmButton = ({ children }) => <div className=“min-w-[200px] bg-green”>{children}</div> ``` Now use a `<ConfirmButton />` everywhere and avoid all that repetition.
- emmacharp 1y agoSome real issues with Tailwind I don't see mentioned as often is they should revolve around the lack of some modern and efficient CSS features and techniques and the inefficient, outdated habits it tends to promote as a result. Over-reliance on media queries and the absence of the clamp() function are just two obvious examples among many others. Performance and browser devtool usability also suffer under Tailwind (compared to good CSS). Since I wouldn't want to waste time on a “dead” thread, I'll stop here. But if anyone is curious and wants me to elaborate, it'll be a pleasure to do so.
- phatskat 1y agoI am curious to hear more, particularly around performance. I also don’t quite grok the bit about “browser dev tool usability”. There’s no reason you can’t add utility classes for clamp() in tailwind, and while I haven’t tried it, you should even be able to do things like `class=“w-[clamp(200px,40%,400px)]”` in Tailwind. A quick look at the docs and there’s an example of inlining calc() this way, so I don’t think clamp() would be any different. Maybe Tailwind could add a clamp utility in the future, eg. `class=“clamp:w-2:w-full:w-16”` to evaluate to `clamp(8px, 100%, 64px)`, seems like that could be useful for avoiding the “over-reliance on media queries”. Side note: I’ll admit I haven’t looked much into the performance issues or inefficiencies of media queries, I’d love to see some writing on that.
- emmacharp 1y agoHello! Sorry for the delay, I thought the thread was indeed dead. Hehe. Maybe you are right about clamp(), but I still think it's only available through “obscure” means if I may say so. So yeah, a clamp utility would help. On performance and DevTools: Take this site for instance: https://bentonow.com https://bentonow.com According to Chrome’s coverage panel, 75% of the CSS is unused on the homepage. I’ve seen this pattern on a lot of Tailwind sites. With native CSS, it’s easier to serve styles just-in-time, alongside related components. That way, users aren’t forced to download styles for pages they’ll never visit. HTTP/3 makes this kind of modular CSS much more viable. As for DevTools, I find them much lighter, simpler, and faster to use with native CSS compared to functional CSS like Tailwind. The DOM is cleaner, and the cascade panel is far more intuitive to explore. Selectors actually mean something and reflect real relationships between content elements. If you want to compare, you can have a look at https://ecss.info/en https://ecss.info/en and then check out any Tailwind site in the DevTools. Happy to chat more if you’re interested!
- blue_waters 1y agoI think there is going to be a painful Tailwind CSS hangover when it's used and copy/pasted via components like Shadcn UI. It really doesn't belong in design kits or UI component libraries (especially if these are packaged - why on earth would want the Tailwind/Postcss processor reaching into node_modules). But as a convenient utility class-based style system for prototype development or simple apps - it has its place.
- persianninja 1y agocheck out daisy-ui (https://daisyui.com https://daisyui.com) if must use TailWind. I hated writing these crazy long tailwind css and viewing them in Developer Tools. Otherwise prob stick to some larger framework like Mantine or Material UI.
- Ray-D-Song 1y agoTailwind is bound to succeed, because JavaScript and JSON succeeded, and so did yaml. The core logic is: People like things that are simple to the point of being stupid, myself included.
- phatskat 1y agoYep! I was a heavy Bootstrap user for many years, along with all the fun of maintaining sprawling trees of SASS files, imports, utility functions etc. I hemmed and hawed when I first had to learn Tailwind - “what are these classes? How does that work? Excuse me what?” But honestly it took very little time to get the hang of it, and with the Tailwind LSP it’s so simple that it seems like using anything else would be annoying at best.