[HN Gopher] CSS's problems are Tailwind's problems
       ___________________________________________________________________
        
       CSS's problems are Tailwind's problems
        
       Author : coltonv
       Score  : 105 points
       Date   : 2025-07-22 16:07 UTC (6 hours ago)
        
 (HTM) web link (colton.dev)
 (TXT) w3m dump (colton.dev)
        
       | jackdh wrote:
       | 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.
        
         | pier25 wrote:
         | > _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 wrote:
           | This 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 wrote:
             | The harm will be in a complicated project where you might
             | have to figure out where some styles are coming from.
        
           | jackdh wrote:
           | My 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 wrote:
             | > _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.
        
       | varbhat wrote:
       | ...then goes on to promote "CSS-in-JS"
        
         | Lammy wrote:
         | Everything old is new again:
         | https://www.w3.org/submissions/1996/1/WD-jsss-960822
        
       | lenkite wrote:
       | 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
       | 
       | 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                   <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
        
         | micromacrofoot wrote:
         | I can't believe people find even half of this acceptable, do
         | they never use a browser inspector in their work?
        
           | aidos wrote:
           | I do, and it's great having the styles right there and
           | hackable.
        
             | recursive wrote:
             | How can styles ever not be hackable? Inline styles always
             | take precedence. What can ever stop you from slapping in
             | more inline styles?
        
             | ericwood wrote:
             | To 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.
        
             | thaumasiotes wrote:
             | Huh? You have the styles right there and hackable
             | regardless of your tooling. That's what browser inspectors
             | do.
        
           | Alupis wrote:
           | If you write enough CSS for a site... eventually you end up
           | building utility classes anyway.
           | 
           | Now, you re-invented Tailwind... but in your own proprietary
           | way that nobody else understands.
           | 
           | Tailwind takes the inverse approach. The example posted by
           | the parent above is _completely unambiguous_ - what you see
           | is what you get, and it 's done the same way everywhere
           | Tailwind is used. You can read the component's styles and
           | understand what it should look like without having to do a
           | bunch of look-ups, or alter classes which might impact other
           | areas.
           | 
           | So now instead of memorizing a bunch of custom classes like
           | `pad-left-20` (because you didn't discover the `leftp-20`
           | your colleague added 8 months ago)... you now have a standard
           | way.
        
             | squidbeak wrote:
             | There's a big difference between using utility classes for
             | utilities and using utility classes for everything.
        
               | 9dev wrote:
               | And here we're on firm bike-shedding territory. Where
               | does a utility stop being a utility and start being... a
               | non-utility?
        
               | H1Supreme wrote:
               | It's less of when it becomes a "non-utility", and more
               | that it becomes an incomprehensible mess of classes on a
               | div.
        
               | Alupis wrote:
               | Honest question... why?
               | 
               | Can you tell me, without looking at the implementation,
               | what effect `btn-atc-primary` applies when the user
               | hovers? No... you cannot.
               | 
               | It's less important to have "clean" looking markup than
               | it is to be unambiguous in intention and implementation.
               | If you read a component that uses Tailwind classes, you
               | know - without any doubt - what it does and what it looks
               | like. That's pretty cool...
        
             | micromacrofoot wrote:
             | You can just write padding-left: 20px; and not memorize any
             | additional layer? If you really love abstraction that much
             | you can do padding: var(--pl20);
             | 
             | Bonus is that you actually know how to use CSS
        
             | antonio07c wrote:
             | In your example you are creating a class for a single
             | property which is what people are complaining about. I
             | would create a .card class that contains the padding (and
             | all needed styles) and probably use a --site-padding
             | variable.
        
             | zelphirkalt wrote:
             | When I write CSS, I think in layers:
             | 
             | (1) General CSS, global effect, like basic font size
             | 
             | (2) semantic components on my pages, like a special kind of
             | list or something, that I give a well thought out name.
             | These CSS definitions are always scoped, obviously to ".my-
             | class-name something" selectors. They cannot affect
             | anything that is not inside a semantic component. It is
             | very simple.
             | 
             | (3) layouts/containers, that contain the components, like
             | some flexbox or grid or something that behaves a certain
             | way, which I also give a meaningful name
             | 
             | (4) A theme, a CSS file that contains CSS variables, which
             | have values used in the other layers. Often when I need to
             | change something, I only need to change my theme.
             | 
             | I do not understand, why web developers en mass are unable
             | to cooperate with each other to develop their semantic
             | units for CSS and then stick to those, instead of
             | sprinkling stuff everywhere and using !important to make
             | shoddy work. If they disagree about the semantic units,
             | then that is the same problem as we have in any other
             | software development arguing how to box things.
             | Furthermore, the semantic units should be part of the
             | design language of the business. The designer should
             | realize "We have 3 kinds of buttons. Each has its own set
             | of rules." and then what is easier than making 3 CSS
             | classes? -- I am sorry, I do not understand where the
             | difficulty is with just using CSS. Someone please, please
             | explain to me, what is the problem in this day and age.
        
           | mejutoco wrote:
           | There was a time when not having css and html completely
           | separate was considered sacrilege. And having html in
           | javascript would have been a mortal sin.
           | 
           | Eons ago I was at a job where we dynamically generated css on
           | the server (php in that project). Anyone would have said:
           | what about separation of concerns? Now everyone says it is
           | best practice to have components with css, html and (gasp)
           | Javascript all in one unit, because someone, for ex. Facebook
           | said it (React). And the truth is it is very useful, and it
           | is another way to structure frontend code.
           | 
           | My point is: it is a spectrum and it can be useful to change
           | the styling right there in the browser inspector. That works
           | with tailwind the same as css. And with components, you can
           | hide the repetition, although the browser will still have the
           | repeated classes. Is this better than having css on another
           | file with maybe some unused classes? I have done both and I
           | can see each has pros and cons.
        
             | vehemenz wrote:
             | The thing is, they were never _really_ separate. The source
             | files were separated, sure, but the way 90% of the world
             | did CSS, there were hidden abstractions relating the class
             | definitions in the .css file and the DOM structure in the
             | .html that weren 't documented anywhere.
        
           | tshaddox wrote:
           | This Chrome extension is widely recommended when using atomic
           | CSS:
           | 
           | https://chromewebstore.google.com/detail/atomic-css-
           | devtools...
        
         | mohsen1 wrote:
         | I used to be against Tailwind. Now that I've used long enough I
         | can tell you that code is perfectly fine. I can read it and
         | easily modify it. You can comment it out if you care
         | <button             class={cn(               // layout &
         | positioning               "relative cursor-pointer overflow-
         | hidden rounded-md",                    // border & background
         | "border border-neutral-950 bg-neutral-900",
         | // padding & text color               "px-3 py-1.5 text-
         | neutral-100",                    // shadows
         | "shadow-md inset-shadow-2xs inset-shadow-neutral-600",
         | // transition               "transition-all",
         | // background gradient positioning
         | "before:absolute before:inset-0",                    //
         | background gradient               "bg-linear-to-b from-white/20
         | to-transparent",                    // hover
         | "hover:bg-neutral-800"                    // active
         | "active:bg-neutral-950 active:shadow-none active:inset-shadow-
         | neutral-800"                    // disabled
         | "disabled:opacity-50 disabled:cursor-not-allowed"
         | )}           >             After           </button>
        
           | cogman10 wrote:
           | Reading though this, I really have to wonder how this is
           | better than                   <button style="css
           | blob">After</button>
           | 
           | Why make a bunch of css classes when it looks to me like the
           | "style" will be roughly the same amount of code and
           | readability.
        
             | chuckadams wrote:
             | You can override classes, not so much inline css.
        
               | cogman10 wrote:
               | Is anyone ever going to override the "px-3" class?
               | 
               | You can also change styles through javascript if you
               | really want to.
               | 
               | It just seems like we've lost the entire reason for css
               | in the first place when every css attribute gets turned
               | into it's own class.
        
               | chuckadams wrote:
               | Special cases in layout are a thing, happens a lot once
               | you start nesting third-party widgets. So yes, there may
               | be enough of a use-case for overriding px-3 that it
               | wouldn't make sense to specifically omit it as a utility
               | class -- to say nothing of it being useful as a utility
               | class to begin with.
               | 
               | I only sprinkle in the very occasional tailwind class via
               | UnoCSS. I don't have the fire in me to dig trenches for
               | either side of this battle that some people want to make
               | all this into.
        
               | mvdtnz wrote:
               | > Is anyone ever going to override the "px-3" class?
               | 
               | No, but they will change things like their constants
               | ("bg-neutral" or, in this case, the spacing constant).
        
             | wwweston wrote:
             | You're correct in the sense that they're both big noisy
             | blobs that dilute semantic/functional signals.
             | 
             | You're neglecting the design system work that goes into
             | tailwind classes. I don't particularly like its choices
             | (and generally consider tailwind to be a minimal local
             | maximum for a set of tradeoffs deserving of faint praise),
             | but they're something, and in an engineering culture that
             | won't adopt a better mindset or better tooling, it's
             | something that solves a few problems well enough.
        
               | dontlikeyoueith wrote:
               | > generally consider tailwind to be a minimal local
               | maximum
               | 
               | I feel like I've been nerd sniped trying to figure out
               | what you mean by this.
        
               | wwweston wrote:
               | Heh, fair, not a super clear phrase. What I'm trying to
               | evoke is that tailwind has a few merits that do produce a
               | local elevation on a few points of front end dev
               | experience... but not much (and for some the tradeoffs
               | cancel it out) and that more is possible.
        
               | shkkmo wrote:
               | It took a sec but I parsed "a minimal local maximum" as
               | "from the set of all local maximums, this local maximum
               | is near the bottom." Thus it is a local maximum, so any
               | small change produces a worse result, but it is one of
               | the worst local maximums you could have found.
        
               | dontlikeyoueith wrote:
               | > Thus it is a local maximum, so any small change
               | produces a worse result
               | 
               | I have ML engineer brain, so to me any small change from
               | a local maximum is an IMPROVEMENT (because we try to
               | minimize loss functions).
               | 
               | Your reading makes more sense.
        
               | nine_k wrote:
               | It's the lowest hill in the range of CSS frameworks, it's
               | not reaching the heights of proper semantic CSS, but the
               | valleys of haphazard, unsystematic style attributes are
               | an even lower point.
        
               | vehemenz wrote:
               | What do you mean by "proper" and "semantic?" The CSS spec
               | never took much of an opinion on how classes should be
               | organized or mapped to elements in the DOM. It's a
               | technical standard. The way people used to write high-
               | abstraction CSS was completely a cultural convention
               | that, in hindsight, overstayed its welcome.
        
             | douglee650 wrote:
             | I am a convert, once you get the hang of the
             | configurability it's very good (Tailwind 4). You don't have
             | to go to separate files which is more streamlined, esp when
             | doing in React.
             | 
             | I like to format in logical chunks per line, for example
             | here's a pretty complex grid setup that is easy to adjust
             | in the template:                   ----         <section
             | className="           w-full           px-8 py-16
             | md:px-16         ">           <div className="
             | grid             gap-2             auto-
             | rows-[minmax(0px,1fr)]             grid-
             | cols-[repeat(1,minmax(4rem,1fr))]             grid-
             | rows-[repeat(1,minmax(4rem,1fr))]             md:grid-
             | cols-[repeat(6,minmax(6rem,1fr))]             md:grid-
             | rows-[repeat(3,minmax(6rem,1fr))]             xl:grid-
             | cols-[repeat(8,minmax(6rem,1fr))]             xl:grid-
             | rows-[repeat(2,minmax(2rem,1fr))]             justify-
             | center             ">         ----
        
             | danenania wrote:
             | The real equivalent to that example would be something
             | like:                 <RetroButton variant="primary" />
        
             | dsego wrote:
             | The style prop doesn't give you a design system, it's just
             | raw values. Maybe you could use something like open props
             | though.
             | 
             | https://open-props.style/
        
             | tshaddox wrote:
             | The simple answer is that inline styles lack support for a
             | bunch of basic stuff like pseudo-classes and media queries.
             | I think the Tailwind team would tell you that they would
             | love to have native web support for full-featured inline
             | styles and that this would obviate many of the reasons to
             | use Tailwind.
        
           | hnthrow90348765 wrote:
           | This is some "put the comma in front of the column name in
           | SQL" logic
        
         | chuckadams wrote:
         | Some judicious use of @apply would go a long way. But for some
         | reason a few years ago they were actively deprecating its use,
         | favoring the above insanity instead. Now @apply seems to be
         | back in good graces, but I guess not everyone got the updated
         | memo.
        
           | cheald wrote:
           | @apply in CSS modules to compose the above sort of thing into
           | something more semantic and readable without creating a bunch
           | of global artifacts is definitely the way to go, IMO.
        
         | crowcroft wrote:
         | Is that more or less verbose than                 button {
         | position: relative;         cursor: pointer;         overflow:
         | hidden;         border-radius: 0.375rem;         border: 1px
         | solid #0a0a0a;         background-color: #171717;
         | padding: 6px 12px;         color: #f5f5f5;         box-shadow:
         | inset 0 1px #525252,           0 4px 6px -1px rgb(0 0 0 / 0.1),
         | 0 2px 4px -2px rgb(0 0 0 / 0.1);         transition: all 150ms
         | cubic-bezier(0.4, 0, 0.2, 1);       }       button::before {
         | content: "";         position: absolute;         inset: 0;
         | background: linear-gradient(to bottom, rgba(255, 255, 255,
         | 0.2), transparent);       }       button:hover {
         | background-color: #262626;       }       button:active {
         | background-color: #0a0a0a;         box-shadow:           inset
         | 0 1px #262626,           0 0 #0000;       }
         | 
         | Sure, separating the code into a CSS file means it's not in
         | your HTML but that doesn't mean it doesn't exist. Similarly you
         | can move the button out to a component and reference that if
         | you want to hide the code.
         | 
         | I find it easier to locate things in the HTML broken into
         | components because the style is co located with the object
         | being styled. I find it much more difficult to navigate through
         | CSS and find out what classes are doing what exactly.
         | Especially when a project grows over a long period of time and
         | different people write CSS differently (and throw a few
         | !important's in to make sure they can meet a deadline).
         | 
         | Each to their own though.
        
           | jakelazaroff wrote:
           | It's not quite apples-to-apples because the Tailwind code is
           | using design tokens and the CSS is not. You should (for
           | example) replace the long `box-shadow` value with
           | `var(--shadow-md)`.
           | 
           | Anyway, to me this question is kind of like asking "Is it
           | easier to break your writing into paragraphs, or write
           | everything in one long block?"
           | 
           | Like, what would you think if I formatted my comment like
           | this?
           | 
           |  _> It 's not quite apples-to-apples because the Tailwind
           | code is using design tokens and the CSS is not. You should
           | (for example) replace the long `box-shadow` value with
           | `var(--shadow-md)`. Anyway, to me this question is kind of
           | like asking "Is it easier to break your writing into
           | paragraphs, or write everything in one long block?" Like,
           | what would you think if I formatted my comment like this?_
        
             | pyman wrote:
             | This isn't something a web developer should be doing in
             | 2025. The styling should be generated by the software used
             | to design the UI.
             | 
             | Why aren't the companies building design tools solving
             | this?
        
               | mdhb wrote:
               | I think you should find a new job.
        
               | pyman wrote:
               | XML developer
        
               | micromacrofoot wrote:
               | Adobe has been trying to build this product for 30 years
               | and still haven't figured it out. Figma is trying and the
               | best you can get is partially usable copy and paste CSS.
               | 
               | This is a "why don't they just make self-driving cars"
               | question. The answer is that there are too many edge
               | cases.
        
             | crowcroft wrote:
             | Most people use Tailwind with components, and so when you
             | talk about breaking things out into paragraphs, that would
             | be the equivalent.
             | 
             | Sure that html looks a bit messy, but once you write it
             | once you're never looking at it again. In your view files
             | you're just writing.                 <Button>Click
             | Me!</Button>
             | 
             | Or perhaps injecting variables etc.                 <Button
             | color="red" style="outline">Click Me!</Button>
             | 
             | I'm not really trying to argue that Tailwind is better or
             | worse, I'm just saying it's a valid way to do things and
             | there's nothing inherently wrong or flawed with it.
        
           | nikkwong wrote:
           | 100% this. People have all of these highfalutin arguments
           | about tailwind being the wrong abstraction/non idiomatic etc.
           | But, as someone who writes a lot of CSS--not having to jump
           | back and forth between a CSS file and a HTML file is a game
           | changer. CSS files are just another thing to maintain, and a
           | painful one at that, since CSS is mostly organized relatively
           | arbitrarily. This is why Tailwind won; reducing the surface
           | that developers have to maintain is a big deal.
           | 
           | There are simply so many decisions when choosing how to
           | implement CSS in a project--where should we put the files,
           | should they be component based or global, what preprocessor
           | if any, etc etc. With Tailwind, you don't have to worry about
           | any of that.
        
           | pluto_modadic wrote:
           | 1. highlighting
           | 
           | 2. syntax checking
           | 
           | 3. language servers.
        
           | vehemenz wrote:
           | There is also additional risk by overusing CSS's built-in
           | selectors and inheritance, whereas there's zero risk with
           | Tailwind.
        
           | wg0 wrote:
           | To each their own, the Tailwind version is more readable for
           | me.
        
         | 827a wrote:
         | There's a lot of people, including oftentimes the tailwind
         | dev(s?) themself, who view Tailwind as a replacement for both
         | CSS and Components.
         | 
         | I think this is an L take. Tailwind is a solid replacement for
         | 99% of the CSS you'll have to write. Its not a replacement for
         | components. It makes components better.
         | 
         | Just wrap that monstrosity in a component; at that point I'm
         | not sure why it matters. Have you ever looked at the component
         | definition for an @mui/material button? Its a cthuluian
         | insanity. The people who maintain that library likely need
         | therapy every week just to remain functional humans. And, I
         | thank them deeply for their service, because I so rarely have
         | to look at those innards; they just work from the outside.
        
         | roguecoder wrote:
         | The power of CSS is that it can capture semantics. Tailwind
         | gives up on all of that.
        
           | zaphar wrote:
           | What? Since when did CSS become about capturing semantics?
           | That's what the Html elements are for. CSS is about the
           | presentation.
        
         | seanwilson wrote:
         | I see buttons used as an example a lot but buttons are one of
         | the most style heavy elements on many websites 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 pretty either.
        
       | dminik wrote:
       | 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.
       | 
       | Just use CSS modules. Just use CSS modules.
        
         | coltonv wrote:
         | I'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 wrote:
           | I 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 wrote:
             | vanilla-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 wrote:
             | I 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?
        
               | jakelazaroff wrote:
               | This is subjective but the DX of writing CSS in JS object
               | syntax is absolutely miserable. Here's an example from
               | the website:                   export const myStyle =
               | style({           display: 'flex',           paddingTop:
               | '3px'         });
               | 
               | I would much (much!) rather write normal CSS and have
               | some build process extract the class name for me, like
               | with CSS modules: https://github.com/css-modules/css-
               | modules
        
       | blain wrote:
       | I'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 wrote:
       | 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?
        
       | eithed wrote:
       | I'd like to hear authors opinions about BEM
        
       | ARandomerDude wrote:
       | > 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
        
       | throwaway290 wrote:
       | 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...
        
       | M4v3R wrote:
       | 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.
        
         | coltonv wrote:
         | > 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 wrote:
       | It works much better with AI though, which is really all that
       | matters at this point
        
         | recursive wrote:
         | That'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 wrote:
         | Is 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 wrote:
       | 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.
        
       | iambateman wrote:
       | 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!
        
         | throwawaymaths wrote:
         | yeah 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 wrote:
           | Also, 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 wrote:
           | AI 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 wrote:
             | Use 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.
        
         | anonzzzies wrote:
         | At least claude code can just global.css without anything on a
         | level that beats anything I see around. And if not, people give
         | me tailwind prototypes, I paste it into CC and tell it I want
         | that and get it in light, pure css without compile, small and
         | fast.
        
       | jakelazaroff wrote:
       | 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.
        
       | mootothemax wrote:
       | Tailwind 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 wrote:
         | A 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 wrote:
           | yeah that's not what I'm saying
        
           | 9dev wrote:
           | With 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 wrote:
           | Because 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 wrote:
       | I 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 wrote:
       | 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.
        
         | vijivishali wrote:
         | I 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 wrote:
           | It 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 wrote:
         | 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.
        
       | theSherwood wrote:
       | The 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 wrote:
       | 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.
        
         | mejutoco wrote:
         | 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.
        
       | directmusic wrote:
       | 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.
       | 
       | 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.
        
       | ahuth wrote:
       | 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.
        
         | roguecoder wrote:
         | ... 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.
        
       | ipsento606 wrote:
       | 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.
       | 
       | Everything else sucks.
       | 
       | [1] https://www.nativewind.dev/
        
       | rc_kas wrote:
       | I 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 wrote:
       | 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.
       | 
       | 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.
        
       | CreepGin wrote:
       | As 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
       | 
       | 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 wrote:
       | In 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 wrote:
       | I 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 wrote:
         | I 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 wrote:
       | Tailwind 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 wrote:
         | Web 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 wrote:
         | The 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.
        
       | 827a wrote:
       | My 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 wrote:
         | Yeah, 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-f...
         | 
         | In Tailwind you could probably replicate this with custom
         | variants or whatever they're called.
        
       | wwweston wrote:
       | This 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 wrote:
         | It is also a great example of where worse is better, when it
         | leads people to doing work they always needed to do.
        
         | treyd wrote:
         | But this isn't unique or new with Tailwind. SCSS and that
         | family of tools had this 10 years ago.
        
           | wwweston wrote:
           | I 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 wrote:
       | Since 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/ 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 wrote:
         | I 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-...
         | 
         | 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 wrote:
         | > 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.
        
         | omnimus wrote:
         | I think the tricky part is that Tailwind (and other functional
         | css frameworks) are loved by 1. complete noobs who dont know
         | css and 2. absolute killer css devs in agencies making content
         | sites.
         | 
         | Most devs on this website work on aplications in big teams
         | maintaining projects for years where css is component scoped
         | and there is time and there are quality checks.
         | 
         | Now when you work in agency you come to a extremely visualy
         | complex product website or magazine. You haven't seen the
         | codebase for a year (or never) and you need to change little
         | thing and add new section to homepage... all without breaking
         | any other part of the website. And while you have 5 hours
         | budget.
         | 
         | In that context Tailwind is best middleground. It establishes
         | system to follow and it is selfdocumenting. Everyone who can
         | read tailwind instantly knows whats going on. And it is much
         | better than inline styles because you can make it responsive
         | and not get to specificity hell.
         | 
         | People here bash funtional css thinking that those who like it
         | don't understand css. I've worked both in agencies and on
         | products and sorry writing css for a CRUD app forms is piece of
         | cake compared to css for beautiful product site where every
         | part is unique and you are required to have deep understanding
         | of how browsers render so you can exploit that inverted
         | position sticky so some ui cards align just right in performant
         | way.
         | 
         | What i am saying is there are many kinds of websites and people
         | who like Tailwind might just be in very different situation and
         | sometimes they might even know way more css than those who hate
         | it.
        
         | vehemenz wrote:
         | > Since Tailwind looks obviously bad on first pass with all the
         | class spam
         | 
         | Why is "class spam" bad? Argument? Go read the CSS spec.
         | There's nothing telling how developers/designers how they
         | should abstract their classes.
         | 
         | High abstraction classes are, I'm convinced, a holdover of the
         | early days of the web when everyone thought XML and XSLT was
         | going to take over the world.
         | 
         | The great thing about functional CSS (especially Tailwind) is
         | that I can see exactly which styles are being applied,
         | immediately, anywhere I want in the DOM. I don't have to
         | consult a separate stylesheet or refresh my browser. There's no
         | context-switching and everything gets built 3-4x as fast.
        
       | jollyllama wrote:
       | Yeah, but, Tailwind has a standalone compiler that lets me avoid
       | NPM, so I'll still use it every time.
        
       | zhengkyl wrote:
       | In regards to developer experience, UnoCSS 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.
        
       | jbreckmckye wrote:
       | I'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 wrote:
         | In 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
        
         | jbreckmckye wrote:
         | (not sure why I said "five years ago" - I learned BEM back in
         | 2014)
        
       | jrub wrote:
       | I 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 wrote:
       | "Tailwind is the Worst of All Worlds"
       | 
       | "it does one thing very correctly"
       | 
       | ... so there's at least one worse world then
        
       | exiguus wrote:
       | I 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 wrote:
       | Early 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 wrote:
       | The 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-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 wrote:
         | I would not expect compression to help performance in the
         | browser??
         | 
         | Bytes transferred, sure, but that's not what OP is talking
         | about
        
       | bonthron wrote:
       | I 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/
        
       | etchalon wrote:
       | Tailwind'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."
        
       | jmuguy wrote:
       | It would be helpful to link to the Tailwind section about
       | duplication 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 wrote:
         | Setting 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 wrote:
       | Just 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 wrote:
       | I 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.
        
       | vehemenz wrote:
       | > 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 wrote:
         | But 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 wrote:
       | I _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 wrote:
         | Oh 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 wrote:
       | I 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.
        
       | huksley wrote:
       | Tailwind 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.
        
       ___________________________________________________________________
       (page generated 2025-07-22 23:02 UTC)