TailwindCSS: Adds complexity, does nothing.
Kerry Boyko

Kerry Boyko @kerryboyko

About: Kerry Boyko is a full stack Node/JS/TS developer, she was the CTO and co-creator of the Mayday PAC, which raised $11M in 2014.

Location:
London, UK
Joined:
Oct 30, 2018

TailwindCSS: Adds complexity, does nothing.

Publish Date: Apr 19 '21
507 260

If you work in the front-end, you've probably heard a lot about TailwindCSS, a CSS library, much like Bootstrap. Much unlike Bootstrap, however, Tailwind takes a different approach - it is all "utility classes".

And I am not a fan. I got a whiff of it and quickly learned the name is appropos: it was as welcome and useful as passed gas.

Before we start, let me try to explain what a utility class is. Let's say that you have many components, and many of them need to have the CSS style property: "display: flex;". Instead of writing that over and over in your css, multiple times, instead you create a class called "flex"

.flex {
  display: flex;
}
Enter fullscreen mode Exit fullscreen mode

Then, in every component that needs to be flexed, you add that "flex" class.

This is not a bad thing. I have written, and used utility classes a great deal myself, especially when I'm writing CSS without the aid of CSS-in-JS solutions or a preprocessor like Sass/SCSS.

What Tailwind does is take that concept to the extreme, with the idea being that you almost never have to write CSS, you just write different classes based on what styles you need to apply.

Which is an interesting choice, because...

This is just inline styles with extra steps

This is just inline styles with extra steps.

That's it. Writing <div class="flex">foo</div> has the same exact effect as writing <div style="display: flex;">foo</div>. Well -- slightly different in that inline styles have higher priority than classes, but that's not really relevant in this context.

So - with that in mind, with the exception of CSS prioritization, any argument you could make against using inline styles in your codebase is also an argument against using Tailwind. For example: Lifewire: Avoiding Inline Styles for CSS Design. Or StackOverflow: What's so bad about inline CSS?. Or LogRocket: Why you shouldn’t use inline styling in production React apps.

I know it seems a bit lazy to rehash other users criticisms of inline styles to explain what's wrong with Tailwind, but it really is a 1-to-1 mapping. It's just inline styles with extra steps.

Some of the problems Tailwind shares with inline styles:

It's WET, not DRY.

When you want to change your site styling in a major way, if you've used utility classes, you need to go through each use of those utility classes - that is, every component - and visually determine what needs to be updated. For example, let's say that your company's primary color is blue. You'll have lots of blue stuff in your website, marked with things like: "text-blue-500" or "bg-blue-300" to determine different shades of blue. And that's fine until your company decides to rebrand, and all of the buttons - but only the buttons - on the site need to be red.

Now you have to go through each component and manually change "text-blue-500" to "text-red-500". And with 1000 edits comes 1000 oppertunities to introduce a bug. It is almost a textbook definition of why the DRY principle is in place.

Alternatively, if you're using regular-old CSS, what you probably did is create a class called ".button". You can just go into that class and change a single line: "background-color: 'red';". Any element that uses that class definition will now be red.

That brings us to the next point:

HTML should only concern itself with the structure of your page, not the styling of the page.

People talk about seperation of concerns a lot in development. CSS Modules (and especially .vue files) have done a lot to dispel the notion that you need to segregate structure, behavior, and style of the same basic building block of your site in seperate folders, but there is something to be said for seperating concerns. That is - each part of your code should be "loosely coupled and highly cohesive."

In other words, your HTML (structure syntax) shouldn't have information about what the styles should be, it should only contain information about the structure of the page.

Indeed, the ultimate reason for the invention of CSS, the whole point of the entire enterprise of CSS... was specifically so that you could seperate content from presentation.

And the method for doing this is through the "class" attribute.

The whole point of "class" is specifically that you can tell the computer what an element is - that is, describe an element's content. Once you've defined the content, then you just need to decide what content of that type should look like.

This not only means that you can go and change how an element looks without worrying about the underlying structure of the page, but also means that you can use these classes to describe what an element is. Indeed, part of the reason for BEM's naming syntax is that BEM names not only tell you what the component is, but also what it's relationship to other components in the document is.

Remember that when we write code, we write it for two audiences: the first is the computer itself, which doesn't care how the code looks so long as it runs, and the other is your fellow programmers. The easier it is for them to quickly identify what parts of your program are and how they interrelate, the more quickly that they can fix bugs, add features, and bring value to the organization.

Which brings us to:

It's hard to read

If you look at some HTML with Tailwind in it, you might say to yourself that the HTML looks "busy" or even "ugly." That's true, but it's missing the point.

Say what you will about inline styles, but they're at least providing enough context to let you know what's happening. Tailwind code is full of semantically obscure abbreviations; most of which are just redefinitions of already well known CSS properties.

Worse still, when they're not redefinitions, they can become downright cryptic. Tailwind prefers to use prefixed class names instead of media queries. Here's an example from Aleksandr Hovhannisyan

So this in Tailwind:

<div
  class="w-16 h-16 rounded text-white bg-black py-1 px-2 m-1 text-sm md:w-32 md:h-32 md:rounded-md md:text-base lg:w-48 lg:h-48 lg:rounded-lg lg:text-lg"
>
  Yikes.
</div>

Enter fullscreen mode Exit fullscreen mode

could be expressed as:

<style>
.thing {
  width: 16px;
  height: 16px;
  color: white;
  background-color: black;
  padding: 0.25rem 0.5rem;
  margin: 0.25rem;
  border-radius: 0.25rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
}

@media screen and (min-width: 768px) {
  .thing {
    width: 32px;
    height: 32px;
    border-radius: 0.375rem;
    font-size: 1rem;
    line-height: 1.5rem;
  }
}

@media screen and (min-width: 1024px) {
  .thing {
    width: 48px;
    height: 48px;
    border-radius: 0.5rem;
    font-size: 1.125rem;
    line-height: 1.75rem;
  }
}

</style>
<div class="thing">Yikes.</div>
Enter fullscreen mode Exit fullscreen mode

Now, the first example, I grant, is an awful lot less code to write, but look at how the second example is explictly defining height and width at specific breakpoints.

It is verbose - as raw CSS usually happens to be, but there are other solutions - such as Sass/SCSS, or solutions such as Emotion, Styled Components, etc. which allow you to use much more terse syntax without losing the cohesive meaning behind it.

Again, this is programmer 101. It's why senior developers get on junior developers for naming variables "const h = 10" instead of "const height = 10"

Another reason why the latter is easier to read than the former - Tailwind's classes are arranged horizontally, while the CSS is written vertically. The wider text is, the harder it is for a reader's eyes to jump to the next line, and the harder it is to find the one particular word you're looking for in a wall of horizontal text.

I bet your eyes started glazing over the second you saw the horizontal scroll bar on that Tailwind code sample, didn't they?

You lose a lot of the features built into standard CSS

I won't harp on this too much, but it should be pointed out that because Tailwind doesn't allow you to use the power of many of CSS's basic features. You can't chain selectors together, like so:

.foo:focus,
.foo:active,
.foo:hover {
  /* css code */
}
Enter fullscreen mode Exit fullscreen mode

You can't use combinators.

.foo p {
  /* all p that are decendants of a .foo */
}
.foo > p {
  /* all p that are direct children of a .foo */
}
.foo + p {
  /* all p that are directly -after- a .foo */
}
.foo ~ p {
  /* all p that are siblings of a .foo */
}
Enter fullscreen mode Exit fullscreen mode

It solves a problem that doesn't exist.

One of the craziest things is that there's an obvious limitation to Tailwind's utility-class paradigm. What happens if you want to group related styles together? Rarely is "display:flex;" used without "justify-content: {value}", for example. CSS allows you to group these styles together into (wait for it), classes.

There's a tool for grouping related Tailwind classes together too. It's called @apply. It's special, non-standard syntax that goes in your CSS file (a directive) and allows you to string together a collection of tailwind classes and place them all under one class name.

That is to say, completely defeating the purpose behind the utility-class paradigm. If you end up having to use @apply, then *why don't you just use normal, ordinary, conventional CSS, which is easier to read, understand, modify, and doesn't require special tooling or parsing. CSS syntax can be complex, but it's been pretty stable since the late 90s, and isn't going to radically change anytime soon.

There's a very simple mental experiment I'd like to conduct with you.

Imagine a world in which CSS was never developed, but something akin to Tailwind was. That is, webpages could only be styled through repeating these individual class names... presumably through using table tags for layout. (To give you an idea of how old I am, I used to code web pages as a summer job in my junior year of high school in 1996 - and we used a LOT of table tags.)

If you could go from the limitations of Tailwind to CSS, wouldn't you consider that a quantum leap forward? Expressive syntax! Semantic naming! Style grouping! Selectors and combinators!. It would be like moving from Assembly to C for the first time. If so, why are we considering replacing CSS with something that does less, is more complex, creates bad quality codebases, and possibly ends up with massive vendor-lock in down the line?

If you want better than CSS, there are already solutions.

So a lot of the hype around Tailwind is that you can get rid of CSS. I know, everyone knows CSS can be hard to work with - especially if you have legacy codebases where the CSS wasn't written that well.

But for the most part, there are other, better improvements on CSS that actually do make styling simpler. There's the various CSS-in-JS solutions that allow you to leverage the power of Javascript to create dynamic class definitions; there's preprocessers such as Sass/SCSS/LESS; there's linters like Stylelint; there's best-practices methods like BEM/SMACSS. Is there overhead in learning these technologies? Yes. Is there tooling that needs to be part of your build chain? Yes. But unlike Tailwind, all of these solutions actively provide a tangible benefit to your code -- which is something that Tailwind can't claim.

It literally provides no value, and tons of problems.

At the end of the day, what do you get for all these problems? What are you left with? You're basically left with a less readable, more complex version of inline styles, a coding technique that we've been trying to breed out of junior developers for the past decade or so.

If you adopt Tailwind, it's going to provide problems for you and your team for years to come, and it's going to be hard to remove it.


Updates based on the comments section.

A few notes based on responses from the comments section.

Why trash something if you don't like it?

It's important to write about bad frameworks as much as it is to write about good ones, because of two reasons.

First, is the John Stewart Mill argument of "the value of the wrongful idea" - that in making a (good faith) argument for something incorrect, one arrives at a more correct, more complete view by analysis and refutation. Ideas must be continually challenged lest they go stale. Indeed - "one who doesn't understand one's opponent's arguments does not understand one's own" is a maxim I try to apply. When I wrote this article, I tried to look for the good in Tailwind. Why do people like it? (They don't have to write css. They can put style info in their HTML. They can write terser code. It gives them power to do things they don't know how to do in css.) Once I knew why people liked it, I had a much better understanding of why I didn't. (It combines content and presentation. It makes things harder to maintain. The syntax is obscure. You lose the power to do things that you can do in css.)

Second is that someone down the line is going to think: Hmm, should I add Tailwind to my app that has to be maintained by my team? And they're going to google "pros and cons of TailwindCSS". There will be plenty of articles explaining the pros. Here's one explaining the cons. Hopefully I've made a compelling argument not to use Tailwind so that future developers won't have to deal with it.

You're being disrespectful to the people who like Tailwind.

This isn't New Orleans Jazz.

I don't like New Orleans Jazz, so I don't have to listen to it. I don't buy New Orleans Jazz albums.

I am not in the habit of making detailed criticisms of what I feel to be the music compositional problems of New Orleans Jazz.

But I have never had a team lead, product owner, or stakeholder come up to me and say: "For the next project, I'm thinking that everyone on the team has to learn how to appreciate and play New Orleans Jazz."

Engineers and developers are often required to work with technology that they not only don't like, but which makes their work harder - often because decision makers either didn't care about the software's tradeoffs, or didn't know. Can't do much about the former, but we can do things about the latter.

When team leaders are thinking about incorporating a new technology into their tech stack, they should look for blog posts like this one to help them evaluate whether or not it's worth a try.

My thesis is not, as you seem to think, "I don't like Tailwind, and therefore YOU shouldn't like Tailwind either". That's a 12 year old's viewpoint of technology criticism.

Rather my thesis is: "If you choose Tailwind for a mission critical application, you will end up making your job harder, your application more brittle, and your team, in the long-term, will suffer."

But CSS has massive problems!

It really does. And there are better solutions than plain CSS. But Tailwind isn't one of them.

Say that in the 1990s, the only way to build a house was to bang nails in with a flat rock (CSS). And then, around the mid 2000s, a really smart guy invented "the hammer." (SCSS) It took adjusting, and you have to learn a new tool, but it did the job much better.

Around the early to mid 2010s, another guy invented the nail gun (CSS-in-JS). It did a lot of the same stuff as a hammer, but you had to know how to use it. There were tradeoffs, but generally, people who chose to work with hammers or with nail-guns usually ended up okay. Many peoplee would often use a manual hammer when the manual hammer seemed appropriate, and the nail gun when they seemed to need it. And all was good in the world of carpentry.

Then in 2017, someone came up to the carpenters and said: "Hey, see what happens when I do this!" and starts hammering in nails with the butt end of a loaded revolver (Tailwind).

And it's supporters quickly point out how more effective it is at building houses than banging in rocks.

"But it's a loaded gun. It might go off and shoot someone"
"Hasn't happened to me yet."
"Why don't you use a hammer? Or a nail gun?"
"I don't like hammers or nail guns."
"I can understand why you might not, but even if you used a rock, that would be safer in the long run."
"But using a rock is so difficult and inefficient."
"I'm not saying to use a rock. I'm saying that the hammer already solves the problems you have with the rock, but even the rock is a better tool for this than a loaded gun because it won't shoot anyone."
"But I love my gun."
"I guess it's alright if you use your gun on smaller projects on your own property, but..."
"Nope, I'm the foreman. Everyone on the site is using loaded guns from now on, because they're awesome."


Update: 9 May 2021 - Check out this blog post by Mykolas Mankevicius which attempts to rebut this article. I disagree, of course, but I think it adds to the debate, and if you're reading this deciding whether to use tailwind or not, you should hear what the "other side" of this issue has to say.

Agree but think my writing style might be too abrasive? Check out Benoît Rouleau's take on this article entitled Tailwind CSS might not be for you

Cher writes about some of the response this article has gotten and how it relates to our own unconcious bias in "Sexism, Racism, Toxic Positivity, and TailwindCSS"

Comments 260 total

  • Daniele Lenares
    Daniele LenaresApr 19, 2021

    Interesting article, a different view about the css "star" of this moment.

    However, let me do briefly the devil's advocate.
    For example, to avoid classes pollution and the "style inline" effect you can use the @apply directive.
    tailwindcss.com/docs/functions-and...
    So you can leverage the simplicity of tailwind without polluting your code.

    • Kerry Boyko
      Kerry BoykoApr 19, 2021

      I briefly touch on the @apply directive in the article.

      The thing about @apply is that you have this utility-class library that doesn't use semantic classes. @apply is then created to convert your utility-classes into something you can use in your semantic class.

      Why not just write the semantic class in normal CSS and cut out the middleman. It's easier to read, more expressive, more powerful, and you don't have to learn a whole new syntax.

      There is one particular case where @apply might be of use - and that's if a programmer knows Tailwind but doesn't know basic CSS... in which case I would not consider that programmer qualified to professionally write front-ends.

      • Alex Layne
        Alex LayneMay 10, 2021

        Because you can use variants defined in your Tailwind config and change them all just by changing the config. Duh. Your condescension is unearned when you couldn’t even figure that out.

  • J.D. Hillen
    J.D. HillenApr 19, 2021

    The Rick & Morty meme really brought it home. Peace Among Worlds Tailwind 🖕

    • Kerry Boyko
      Kerry BoykoApr 20, 2021

      F**k you! (It means "Much obliged.")

      • Alex Layne
        Alex LayneMay 10, 2021

        As a fan of Rick and Morty, I totally understand why people view fans of the show as insufferable douchebags. Case in point here.

  • Dylan Anderson
    Dylan AndersonApr 19, 2021

    A bold article to write seeing as how it seems Tailwind is the starchild of CSS these days. But, an article I think needed to be written. I share most of your views on Tailwind.

    I even tried to start a project from scratch using Tailwind because I thought "it's really popular and it looks really pretty - maybe I just need to buckle down and use it". It took me a few days until I came to your same conclusion - why don't I just use plain CSS (or in my case, SASS since I was already using it)?

    It seemed silly to write:

    .button{
        @apply px-4 py-2 rounded-lg
    }
    
    Enter fullscreen mode Exit fullscreen mode

    when that's basically the same as:

    .button{
        padding: $padding-lg padding-md
        border-radius: $border-radius-lg
    }
    
    Enter fullscreen mode Exit fullscreen mode

    and yeah - it's a lot less clear exactly what's happening. In my book, clarity always trumps cleverness.

    The colour scheme is nice though, so I usually import it into my SASS files.

    • Jed Ashford
      Jed AshfordApr 20, 2021

      To someone more familiar with raw css, then that's going to be more clear. After using tailwind for a few days that syntax starts to be easy to understand. I'd argue actually much easier to know what happening than long lists of cryptic css commands.

      A few:
      w-full width: 100%;
      w-screen width: 100vw;

      container: The container class sets the max-width of an element to match the min-width of the current breakpoint.

      How about a simple ring around a component?
      Use 'ring'
      In css: box-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
      ring-inset --tw-ring-inset: inset;

      All of this can be done using other libs and dependencies, but tailwind sure makes it easy.

      • Kerry Boyko
        Kerry BoykoApr 20, 2021

        Even the things that Tailwind "simplifies" are made more complex, and "ring" is a perfect example.

        I'll admit, rings are difficult in CSS, which is why if I need to make one, I usually end up writing my own utility class for it.

        But even looking at "ring" you end up having to add 5 classes or more to get your ring styled the way you want it. So "ring" ends up being "ring-3 ring-blue-300 ring-opacity-50 ring-offset-0 ring-offset-red-500" by the time you actually use it.

        On the other hand, you could define all those into an actual utility CSS class, call it ".branded-ring" and just use that wherever you need it (instead of having that long string of five classes everywhere in your file.) Or even better, you could write branded-ring as a SCSS variable or a bit of styled component css`` code. If you use a CSS-in-JS solution, you could even have the color of the ring change according to props, giving you behavior control over style.

        And it would be more readable, more customizable, and then you don't have to worry about it. You would be able to write it once, and then your entire team could just import your code and reuse it - rather than every developer having to remember how to tailwind-style a ring every time they use that.

        Of course, rings aren't that difficult to do, because Google is a thing that exists, and there are a dozen websites which explains how exactly to do it.

        Of course, what happens when the CSS spec updates and rings are added due to popular demand? It happened with flexbox. It happened with css-grid. You never know.

        • Reinier Kaper
          Reinier KaperMay 8, 2021

          You can use @apply, which does the exact same thing.
          It allows you to make a single class .branded-ring while still leveraging Tailwind's classes.

          • Ben Sinclair
            Ben SinclairMay 10, 2021

            You can do that in things like Sass, too. It's not a benefit of Tailwind.

            • Reinier Kaper
              Reinier KaperMay 10, 2021

              But that's the point. It's not a good example of how using regular CSS (or pre processed CSS) is "better" in this case, it's not.

              • Ben Sinclair
                Ben SinclairMay 10, 2021

                I'm not sure I follow. I'm saying that having the same feature as an existing build process doesn't make the new one better, it makes it the same. I'm saying that the claim is that BMW make better cars than Ford because BMWs have four wheels.

                • Reinier Kaper
                  Reinier KaperMay 10, 2021

                  It's not a valuable claim in the original article.

                  He doesn't like/use Tailwind as he doesn't see the benefit over using what he already does.

                  That's fine and totally reasonable, but it's not an argument against Tailwind. His whole article is about how Tailwind is useless.

                  Maybe to him it is, fine, no one argues that. But that doesn't make Tailwind useless in general.

                  His examples are supposed to show how bad Tailwind is. It isn't. It just doesn't fit him or his way of writing CSS.

                  Cool, absolutely nothing wrong with that, but again that didn't make Tailwind useless or bad in any way.

    • Raghav Misra
      Raghav MisraApr 23, 2021

      lol same for that last thing

      • АнонимApr 24, 2021

        [deleted]

        • Kerry Boyko
          Kerry BoykoApr 25, 2021

          I am coming up with a better solution. Working on it now.

          • АнонимApr 25, 2021

            [deleted]

            • Raghav Misra
              Raghav MisraApr 26, 2021

              It's a criticism of an open source project, quite the opposite of a personal attack lol.

              • Tanzim Ibthesam
                Tanzim IbthesamApr 26, 2021

                Go and read the full article he attacked people who use Tailwind and expressed judgements. There is difference between constructive criticism n personal attack. everything in this world has pros and cons he could not provide any rationale arguments you can critisize and bash everything and if you think people who are using are fools then make a solution better than Tailwind. Enough is enough he expressed his thoughts I expressed mine I dont know him you dont know me lets lave this.

                • Ashley Sheridan
                  Ashley SheridanApr 26, 2021

                  @tanzimibthesam you can't on the one hand criticise Brian for writing an article against Tailwind and demand that he must provide a better solution before pointing out the problems with Tailwind, and then lambast him for doing exactly that.

                  In the field of development, we should regularly challenge the de-facto ways of doing things, and always be asking if the tool/method/etc is really the best thing to use in a given scenario. It's how the entire industry moves forward. We can question and bring forth discussion about things with articles and posts like this one. You don't have to agree with it, but it shouldn't warrant personal attacks or profanity.

                  • Tanzim Ibthesam
                    Tanzim IbthesamApr 26, 2021

                    He has to provide a better solution cause something is called personal criticism and one thing is called bashing and saying everyone is wrong who is using it.He is doing personal attacks and providing negative vibes. Stop defending this silly man. You dont know him and I dont know you or him neither nor he is providing a solution nor people are gonna stop using Tailwind.

                    • Ashley Sheridan
                      Ashley SheridanApr 26, 2021

                      He doesn't actually have to provide a better solution to anything if he wants to write a post pointing out what he feels are problems with that thing.

                      As for personal criticism, I can only go on what I saw on this whole thread. This involved him making some points that he felt were issues with Tailwind, and you throwing insults and profanity at him in replies. The only personal attacks I saw were from you. You're right in that I don't know him, I'm fairly impartial in this, although I do happen to agree with his criticisms of Tailwind.

                      As for him providing a solution (as I've said, he has no requirement to do this, it's akin to a non-driver pointing out problems with a bad motorist, or a non-artist highlighting parts of an ugly painting), he did actually mention he was working on something (and provided a link), for which you attacked him again. Those comments of yours appear to be deleted now, so I can't provide exact quotes, but I believe you did mention his proposed linked solution was a waste of time, bloated, and pointless.

                      • Tanzim Ibthesam
                        Tanzim IbthesamApr 26, 2021

                        Yup leave it man peace 😂

                        • Kerry Boyko
                          Kerry BoykoApr 26, 2021

                          Not to re-open this, but I get a smug set of satisfaction from the fact that Airfoil has already been declared "bloated" despite the fact that A) it hasn't been written yet, B) the point of Airfoil is that you only really get value from about 9 of Tailwind's 300+ classes, so why not just write those nine in a way they can be reused and integrated?

                          I understand putting so much of your identity into, say, a political movement that when someone makes criticisms of the political movement - no matter how valid - you feel personally attacked. But I don't understand how you can do this with a css framework.

  • Jed Ashford
    Jed AshfordApr 20, 2021

    For us web dev isn't massive part of our business and kicking media queries into the dark abyss was satisfying when moving to tailwind.

    A few things.

    1. Tailwind-jit solves most of the concerns you listed with chaining, exact colors and values, etc. This should be a must and they're trying to get merged into the main project.
    2. Using Sass, we can compile tailwind into css classes. So you get the best of both worlds.
    3. Even senior devs appreciate anything like tailwind 'container' that does all of the calculations for you. Many of the classes provided are more powerful and easier to use than pure css. Plus you don't need to choose one or the other cause you can use both.
    4. How often are you rewriting styles across your website that you must have global css? Any of that is already externalized to the tailwind.config file. I've never rewritten a site/pages without having to start over with new html and css. Just comes with a redesign.
    5. Media queries are a thing of the past. So many abstracted queries across the project. min-width? max-width? Which way does that go again? Not explicitly defined in the html, so you're left guessing often why your css changed. All these queries are gone often with a simple sm:flex class and it lives with the html it alters. This is by far the most powerful and follows the proximity principle of development.

    I wish you luck, always fun to learn something new and see how the community can alter development.

    • Kerry Boyko
      Kerry BoykoApr 20, 2021

      Interesting.

      I would say that even if web dev isn't a massive part of your business, then why would you want to deal with Tailwind anyway? You're not really skipping out on the bulk of complexity of CSS, you're just writing CSS using an alternative syntax that maps 1-to-1 to actual CSS. It doesn't make it any easier.

      Compare that to something like Bootstrap, which does make things like breakpoints, media queries, etc. easier. Yes, it's more opinionated, and "bootstrap sites look like bootstrap," but if web dev isn't a massive part of your business, then that's all you need.

      And while you can compile tailwind into CSS classes (with either Sass, as you mention, or @apply) -- why would you want to? Why not just write the class directly, skip the middleman?

      As for "container" - yes, it's easier to write 'container' than it is to fix max width at all media queries... the first time. But once you've done it once, it's easier to reuse. Now, if Tailwind were just a collection of commonly used CSS utility classes, I'd say that it has value, but "container" is a massive exception to the rule. 99% of tailwind is just one-to-one mappings of CSS properties.

      In fact, I'd be surprised if someone hasn't written a very stripped down version of Tailwind that is just a single CSS file with "container" and one or two other cherry picked utilities. If they haven't, I might write it myself.

      How often are you rewriting styles across your website that you must have global css?

      I work at a consultancy. The answer can be "very," depending on the client's whim. But aside from that, the main reason I might rewrite a style is because it's a bug fix, and in that case, I'd rather have to fix the bug in one place rather than fix it in 100.

      Media queries are a thing of the past.

      Yes, but it's not like Tailwind invented the 760 grid system. If all you want is to avoid writing media queries everywhere, there are already tons of great libraries for doing that.

      My problem isn't that there aren't some examples of good code out there in Tailwind. My problem is that it's 99% bad code, and the 1% of good code has been done, better, elsewhere.

  • Mateo Tibaquirá
    Mateo TibaquiráApr 20, 2021

    Tailwind is making a lot of money nowadays, but the time will tell...

    • Ben Sinclair
      Ben SinclairMay 10, 2021

      I don't think making money is a useful metric for anything else except how much money you make.

  • Cody Seibert
    Cody SeibertApr 20, 2021

    It’s not the future bro. It’ll probably fade away when the hype is over

  • Cody Seibert
    Cody SeibertApr 20, 2021

    I tried it out, I’ll stick to BEM or SASS.

    • Alex Layne
      Alex LayneMay 10, 2021

      The most unreadable CSS I’ve ever seen was in BEM. You can use SASS with Tailwind.

  • Michael Cohen
    Michael CohenApr 20, 2021

    First of all, be nice. :)

    Second, it's obvious from the article + comments that there are both advantages and disadvantages to Tailwind vs. CSS. Tailwind's advantages sound like they work well for you, and how you code things. For other developers, such as the author (or myself), Tailwind's "advantages" aren't beneficial at all, and are instead roadblocks on the way to coding up a design in a clean, robust, and self-explanatory fashion.

    I'm glad Tailwind works for you, but just because that's the case, don't trash other people's preferences. :) Have a great day! :)

  • Jack
    JackApr 20, 2021

    I'm not sure why tailwind is so divisive, I've not met anyone who thinks it's "okay", we either love it or hate it.
    Personally I love it and here's why:
    I've always hated external css files, or one monolithic global css file. Looking at some html and then spending 5 minutes trying to work out what ut looks like was always frustrating. Sometimes SoC isn't a such a good thing. You mention Vue, but Vue's SFCs were actually made to increase the coupling of your html/css/js!
    You can't do media queries with inline styles.
    Tailwind let's you abstract your units. This is one of the biggest pros for me. I can use a class like p-3 in multiple places, but if I decide I want bigger spacing, I can just update my tailwind config and all of my p-3 elements will update. You mention colors, but these are just tailwind's defaults. In reality you would configure tailwind to have primary and secondary colors, e.g. bg-primary-light. Then when your cpany decides to rebrand, it's super easy.
    If you don't like how you end up with super long class names, there are simple solutions. I use a simple concat library to split my classes into multiple lines. I group my classes either by breakpoint or by area (like all flex related classes) and it's really readable.
    On the same topic, if you're using something like react tailwind should actually encourage you to make more components. All of my tailwind classes are neatly tucked away in low level components. My application level components are incredibly terse and have no styles or classes on them.
    But the biggest win for someone like me, is I can just "get on". I don't have to worry about coming up with BEM names, or where to locate my styles, or how to keep spacing consistent, or compiling sass. I can work on the stuff I love (functionality) with the confidence that it will look good and consistent.

    That said, I get a lot of the reasons people don't "get" it. But if you were to join my team I'm afraid you'd just have to get over it! 🤣

    • Kerry Boyko
      Kerry BoykoApr 20, 2021

      I get it.

      I honestly think that Tailwind might be a good fit for you and your projects at this time.

      I actually think a better fit might be a more opinionated framework, such as purecss.io/ - but forget that for right now.

      If you are designing websites as a secondary consideration, if you're not comfortable with CSS, if you just want to "get on" with your structure and behavior, then maybe I can see it. In this type of scenario, I could see how Tailwind might be used as a rapid prototyping tool to try out different designs, but that once a design is settled upon, Tailwind code is rapidly stripped out and replaced with a more scalable, maintainable solution.

      If I were to join your team, yes, I'd get over it. I'm a professional - if my team lead were to go with Tailwind, I would explain my concerns, state that I believe it to be a large mistake, but at the end, follow the team lead. That's what you do. Make your case to the guy who makes the call, then follow the call.

      But if I was team lead, and one of my experienced senior engineers were telling me that a framework I was considering was completely worthless and would generate tons of technical debt for no appreciable value, I'd at least pause and think about what he was saying before plowing ahead.

  • Sm0ke
    Sm0keApr 20, 2021

    The title is super funny.
    .. <('_')> ..

    • Kerry Boyko
      Kerry BoykoApr 20, 2021

      I almost named it: "TailwindCSS: If it's named like a fart, and it smells like a fart..."

      But that would be slightly unprofessional, so I toned down the obvious joke and buried it to the third paragraph.

      • Alex Layne
        Alex LayneMay 10, 2021

        Ah yes, comparing someone’s hard work to a fart in the body of the post is not at all unprofessional.

  • DavidMulder0
    DavidMulder0Apr 20, 2021

    I think "inline styling with slightly different tradeoffs" or "slightly different syntax for writing classes" surmises the two ways Tailwind can be used. The former is perfectly sensible for 'single-use' code (e.g. a lot of websites rather than web applications are expected to expire within a couple of years at most), the latter is a lot more questionable for me. I often talk about how when you have a custom solution and a standard the custom solution should offer great benefits over the standard to be picked.

    Aside of what you already mentioned I think there are two more angles to be considered: Tailwind as an alternative CSS syntax introduces a lot of abbreviations (Reminder: "Code is written to be read by humans, not computers") and it's like having to learn a new language without any certainty that anybody will use it down the line. Additionally I think some of the popularity of Tailwind is coming from people less familiar with new CSS features. Many comments talking about the advantages of Tailwind will often talk about the advantages of things such as flexbox and grid layout. This then results in these people further postponing learning these properties properly, making Tailwind basically an underarm crutch (the type of crutch which ends up harming the patient) for those people.

  • Sameer Chandra Nimushakavi
    Sameer Chandra NimushakaviApr 20, 2021

    Thanks for writing this article. I felt that I was the odd one out who doesn't feel productive while using Tailwind. Glad to know that there are many. I prefer writing my own sass

  • intermundos
    intermundosApr 20, 2021

    Now we get a post of tailwind every week.

    To summarise quickly - you don't like it, don't use. No need to shout out that it's so bad, no one should ever use it.

    • Kerry Boyko
      Kerry BoykoApr 20, 2021

      It's important to write about bad frameworks as much as it is to write about good ones, because of two reasons.

      First, is the John Stewart Mill argument of "the value of the wrongful idea" - that in making a (good faith) argument for something incorrect, one arrives at a more correct, more complete view by analysis and refutation. Ideas must be continually challenged lest they go stale. Indeed - "one who doesn't understand one's opponent's arguments does not understand one's own" is a maxim I try to apply. When I wrote this article, I tried to look for the good in Tailwind. Why do people like it? (They don't have to write css. They can put style info in their HTML. They can write terser code. It gives them power to do things they don't know how to do in css.) Once I knew why people liked it, I had a much better understanding of why I didn't. (It combines content and presentation. It makes things harder to maintain. The syntax is obscure. You lose the power to do things that you can do in css.)

      Second is that someone down the line is going to think: Hmm, should I add Tailwind to my app that has to be maintained by my team? And they're going to google "pros and cons of TailwindCSS". There will be plenty of articles explaining the pros. Here's one explaining the cons. Hopefully I've made a compelling argument not to use Tailwind so that future developers won't have to deal with it.

      • intermundos
        intermundosApr 20, 2021

        I agree that it's important to write both good and bad stuff.

        Is also important to mention good things tools bring and not only subjective opinion on the bad stuff only. Why not mention both advantages and disadvantages if the aim is to give perspective for those looking to use the tool?

        The title and the article itself is written in a negative manner, which is much more like "hey folks, I tried tailwind, I don't understand all the pros, don't understand how it can improve solo/team work, but will pour lots of shit on it'

        Sad.

        • Kerry Boyko
          Kerry BoykoApr 21, 2021

          The problem with "why not mention the advantages?" is that there needs to be advantages worth mentioning.

          I mean, I agree with you. There are lots of tools for programmers out there that provide both advantages and drawbacks**.

          Before I became a programmer, I actually was a journalist, and one of the things that my co-workers and J-school professors hated was the idea of false equivelance. The typical example is that 99% of scientists would agree climate change is real and manmade, while 1% may disagree, and to give the appearance of showing "both sides", cable news networks would book, on one side, a fringe skeptic, and on the other, a scientist. Or more likely, Bill Nye the Science Guy.

          I'm not going to mince words - if I can't find a single positive thing to mention about a tool, I'm not going to go out of my way to scrape the bottom of the barrel to find something.

          The thesis of the post is that Tailwind adds nothing. That there are no advantages to be had.

          ** A good example: Mongoose ODM for MongoDB. I personally wouldn't use it - I think it's too much boilerplate and cruft to add ORM-like structure to the relatively simple syntax provided by the MongoDB native Node drivers, and I don't like the performance hit when I used it (back in 2015). But the advantage is that you can organize how you interact with your DB in a standard way, follow existing models established by decades of relational DB management, and help to acclimate established SQL-heads to Mongo. Mongoose has advantages and disadvantages.

          • intermundos
            intermundosApr 21, 2021

            Yes there is almost always both advantages and disadvantages. And it is on every individual developer / team to decide what works best for them.

            And it is on the author to cover both sides to provide reader with constructs which will help to choose or reject the tool.

            • Kerry Boyko
              Kerry BoykoApr 21, 2021

              In this case, there are no advantages I could find, only disadvantages.

              I suppoes the fact that I could find no advantages but plenty of disadvantages should people decide whether or not to use the tool.

              • Ben Sinclair
                Ben SinclairMay 10, 2021

                And it is on the author to cover both sides

                I don't think this is something you can say about articles in general. It's perfectly fine to have an article that says, "I love X because Y" without mentioning its drawbacks - especially on a forum like this, where people will bring up their criticisms in the comments. It's responsible of the author to address those criticisms - or even to say something like, "I don't mind the drawbacks, I expect it to improve in the future" which acknowledges the criticism and moves on.

                OP has already said they don't consider the claimed advantages to be legitimate.

      • Mickey
        MickeyApr 22, 2021

        Why tag the frameworks "bad" or "good"? Who are we to decide this for others?

        If you don't like it - don't use it.
        If you like it - use it.

        We can take ANY framework and find people who hate it and those who love it.

        We are free to express pros and cons of anything, but why not be respectful?

        Why trash something if you don't agree with it?

        I know many people and companies that love TailwindCSS and appreciate it.

        People are putting much effort to produce something that they believe is helpful and will solve problems many of us have. The majority of feedback about TailwindCSS is very positive.

        And then other people, based on their OWN PERSONAL preferences, pour dirt on their work.

        That's just disrespectful.

        • Kerry Boyko
          Kerry BoykoApr 23, 2021

          Why tag the frameworks "bad" or "good"? Who are we to decide this for others?

          We are software engineers. And what seperates "software engineers" from software developers is that while the developer can make something, the engineer evaluates, plans, and figures out the best way to make something before making it.

          That means we have to take a look at proposed code and proposed tech. We have to take a critical eye to it.

          Why trash something if you don't agree with it?

          Because this isn't New Orleans Jazz.

          I don't like New Orleans Jazz, so I don't have to listen to it. I don't buy New Orleans Jazz albums.

          I am not in the habit of making detailed criticisms of what I feel to be the compositional problems of New Orleans Jazz.

          But I have never had a team lead, product owner, or stakeholder come up to me and say: "For the next project, I'm thinking that everyone on the team has to learn how to appreciate and play New Orleans Jazz."

          Engineers and developers are often required with working with technology that they not only don't like, but which makes their work harder. So when team leaders are thinking about incorporating a new technology into their tech stack, they should look for blog posts like this one to help them evaluate whether or not it's worth a try.

          My thesis is not, as you seem to think, "I don't like Tailwind, and therefore YOU shouldn't like Tailwind either". That's a 12 year old's viewpoint of technology criticism.

          Rather my thesis is: "If you choose Tailwind for a mission critical application, you will end up making your job harder, your application more brittle, and your team, in the long-term, will suffer."

          You may disagree with that thesis, but you need to provide evidence to back your position, and "But I like it, and other people and companies like it, so shut up, you're being mean" is not an adaquate, professional rebuttal.

          • Mickey
            MickeyApr 23, 2021

            So will we see an article from you about how shitty New Orleans Jazz is and why no one should listen to them because you said so?

            I wanted to answer your comment with examples of articles discussion pros and cons of TailwindCSS,
            but decided that you seems to have much more time to write long answers than I do. Plus, having M.A. Journalism must help you with the language... not a lot, as the language you use is not of a high level.

            Anyone can google for "tailwindcss pros and cons" and see that there are many results, most of them are pro TailwindCSS, others discuss the cons in polite professional manner, as opposed to your low level mocking language.

            My personal experience (I started in 2005, if that's means something, and it does, since you mention your 12 years of experience), is that at my work we had a project to revamp the UI and a guy was hired, we asked him to do it right, CSS-wise he should use SCSS+BEM, and he did.

            The product looked good, any changes along the way were fast.

            He was the only doing the revamp. Then this guy left and 10 FE developers were left with the CSS. When any of those 10 people needed to look at the CSS that was written and change something, it was a quest. No one understood what was going on and how to find styles, because it was all SCSS functions and mixins. Hundreds of lines of code. Tenths of BEM classes.

            We came to a conclusion that we need to throw the new-old CSS as fast as we could.

            Then we got introduced to TailwindCSS and tried it on an isolated module. Everyone loved it. We moved faster than ever. We had maybe 50 lines of pretty formatted custom SCSS for that module.

            The team loved working with TailwindCSS so much, that when this modules was merged into the main application, a pretty huge one, the rest of the people learned to use and utilize it in a matter of hours and there is no a single person in the team who doesn't want to use TailwindCSS now.

            We are progressing really fast and we have very few custom SCSS to maintain and it's easy. Never been easier. And it is extremely maintainable. Plus - prototyping during live sessions with our UI is just a joy.

            (That came out longer that I expected).

            I can take every point and example you presented from your narrow point of view and make an argument how to change it a little to make it work much nicer than with plain CSS. But many here tried and I don't see the point. If one does not want to see the side of the other - there cannot be a dialog, learning and collaborating.

            As many technologies, there are beset practices and design patterns that are emerging, and you didn't mention any of them or mention them in such a way that they looked bad.

            So, again, if you think that technology A is not for you and you are sure (no idea who put you into a position to decide for anyone) that it's bad - present the cons, but do it at a level that people will pay attention and not is an unprofessional way you did here.

            (I used "professional" and "unprofessional" a lot, because you seem to enjoy using it to describe yourself)

            • Kerry Boyko
              Kerry BoykoApr 24, 2021

              So will we see an article from you about how shitty New Orleans Jazz is and why no one should listen to them because you said so?

              You didn't get the point at all, did you?

              Plus, having M.A. Journalism must help you with the language... not a lot, as the language you use is not of a high level.

              On the contrary, the fact that the language I use "isn't high level" is a massive compliment. :)

              I came into J-school from a B.A. in History, and a 720 on the GRE's verbal section. I knew, and used, a lot of sophisticated, convoluted words. My vocabulary was labyrinthine and circuitous when I really wanted to show eggheaded impertinance.

              My first J-school assignment came back with a lot of red ink on it. "Use the smaller words," it said. "Write for a smart 13 year old - someone with an 8th grade level of education."

              The reason why is because the job of a journalist is to communicate ideas and information, not to obscure them behind flowery language.

              Now I'm not going to say that I'm a professional journalist today, but one of the things I can still do well is communicate. If you work in tech, the ability to communicate complex ideas to your team simply is possibly the most important skill you need to know. And to do that, I try to use small words instead of big ones.

              There are a lot of really good programmers who might not have a collegiate reading level in English (second-language, self-taught, still young), and I want to communicate to them, too.

              So - I know you didn't mean it as a compliment, but thank you.

  • Ranieri Althoff
    Ranieri AlthoffApr 20, 2021

    Now you have to go through each component and manually change "text-blue-500" to "text-red-500". And with 1000 edits comes 1000 oppertunities to introduce a bug.

    Ah, if only there existed search and replace...

    • Rubin Elezi
      Rubin EleziApr 20, 2021

      Search and replace does not work all the time, as sometime you have to apply logic to it. Maybe you want to update only 763 elements.

      • Ranieri Althoff
        Ranieri AlthoffApr 20, 2021

        In that case, you will still need to go one by one changing the class if you just put "button" in all of them.

        • Kerry Boyko
          Kerry BoykoApr 20, 2021

          You shouldn't. If the class is .button, and the .button class is only defined once, then one change to the .button class definition in your css should apply to all items that have the .button class.

          I should have been clearer in my example by using something like ".branded-button" but you do see how you don't have to go in one by one, right? Because you're not changing what the class is named, only what the class does.

          • Milan
            MilanMay 2, 2021

            You often create a component for these scenarios, making different button components and reusing them. This pattern follows DRY too and also gives you the tooling and productivity of tailwind.

    • Chris Partridge
      Chris PartridgeApr 20, 2021

      Or just create a custom color palette in your Tailwind config called 'brand', set your colors and be done with it. If brand colors change, update the color palette - easy.

      • Kerry Boyko
        Kerry BoykoApr 20, 2021

        Right, but branding is more than just color palettes. It's also - do we want the corners to be more round or less round on buttons. What if we want to have switch toggles instead of checkbox toggles? What if we want a specific page to look like a specific brand that isn't our main brand?

        (This happened with a client of ours which sold Louis-Vitton gear -- Louis-Vitton wouldn't allow them to sell LV stuff on the client's page unless the pages that they landed on were branded with Luis-Vitton's color scheme).

        • Chris Partridge
          Chris PartridgeApr 20, 2021

          Right, and Tailwind offers plenty of flexibility to manage these things via your config if required. It's not just a static set of a utility classes that cannot be altered without digging into the source - override the default border radius settings, or create your own presets for your brand if need be.

          The exact use case in your article and comment (branded button) is mentioned in their documentation somewhere (I distinctly recall reading it), and I'm sure they suggest creating your own branded button class using @apply. If your branded button border radius requirements change, update the class, if the new border radius is outside the presets, then extend the config and then update the class.

          If a specific client demands you brand their pages, then add a color palette for their brand, and make sure those components switch out brand for client-brand where required? Tailwind certainly doesn't stop you from using colors outside their default palette - I've only ever used the provided colors for non-brand accenting (e.g. greens for success, reds for errors, etc) and the grays for text/borders.

          In regards to moving to switch toggles from checkbox toggles, you're likely going to adjust the layout of the component somewhat, or perhaps add an additional container element ensure things are aligned correctly - I've encountered this exact type of scenario many times over the years - more often than not, it's more than just a few lines of CSS.

          And if you're building a modern application, you'll likely have a checkbox component or at least a rudimentary template/partial to stay DRY - which will prevent the need to update every occurrence of that particular component across your application - again, something which I believe they touch on in their documentation.

          To be frank, I wasn't a fan of Tailwind at first, and I certainly don't think it's the "be-all and end-all" solution - but after using it on a few projects I've come to love what it offers out of the box (especially the font, text sizing defaults, colors for accenting, gray set, grid, gradients, screen breakpoints, space-between, etc) with the ability to extend/override anything I desire if the case arises.

          It's really allowed me (as a full stack developer building business applications) to start flowing without having to worry about any of aforementioned when I just want to get something clean, consistent and functional on the screen.

          With all that being said, if you're creating basic web sites, landing pages, marketing pages - or complex applications without a component framework - Tailwind probably isn't the solution you want.

          • Kerry Boyko
            Kerry BoykoApr 21, 2021

            The problem is that the minute you start using @apply and using semantic classes again, you're moving outside of Tailwind's "utility classes" paradigm.

            Now - while I could argue that "you might as well just write out the CSS" there is some value to alternative syntaxes. There's all sorts of tools for transpiling non-standard code into standard code. Typescript -> Javascript, Coffescript -> Javascript, ES2015+ -> Babel -> ES5, Sass -> CSS, SCSS -> CSS, LESS -> CSS, Knex -> SQL...

            It would be an interesting -- and I think worthwhile! -- project that would use only @apply in CSS files and then transpile them (maybe with SCSS) into the appropriate CSS around the same time you're transpiling all those "$" prefixed variables, Sass functions, and "&" notation. If you want to have a tool that is designed to make @apply px-5 shorthand for padding-left: 5rem;
            padding-right: 5rem;
            then that would be an interesting tool that wouldn't break semantic structure.

            • Chris Partridge
              Chris PartridgeApr 21, 2021

              I've had the same thought - and it's essentially what I've been playing around with on a Svelte project with Tailwind's JIT mode. All the component markup, script and style tags are self contained in their own .svelte files - using @apply in classes within the style tag.

              Certainly makes the mark up a lot easier to reason with when you have a lot of nested elements and many utility classes applied - I won't argue that fact.

              The only issues I can see are:

              1) Each components generated CSS classes are included in their own style tag within the head element, so I'm not sure what sort of performance issues this might cause if you have a lot of components.

              2) Any class used with @apply within the svelte components, gets marked as "used" by Tailwind and ends up being compiled into the stylesheet loaded on the page. So if you don't use those utility classes in the mark up (and only in classes), they are essentially dead weight.

              I'm sure neither issue would be difficult to resolve - either way, it's interesting none the less!

              • Mike Ciccone
                Mike CicconeMay 7, 2021

                See, and this is the problem with writing a very opinionated article without understanding it. Tailwind is trying to get you away from using the @apply method. They have mention that in multiple tweets, articles, and videos.

                Instead of @apply bg-blue-500 for your brand you can easily set a color theme of "brand" in your config then use your theme in the css. ie:

                .button {
                background-color: theme('bg-brand-500');
                font-family: theme('fontFamily.brand');
                ///and any other variable you have set in your tailwind config.
                }

                then you just change your tailwind.config when you need to and you are done. Same as using a sass variable etc. It's not that hard and completely follows a dry principle.

                • jimkeller
                  jimkellerOct 18, 2022

                  How is this an improvement over CSS variables though? Why not var(--color-bg-brand-500) ?

      • Geoffrey Swenson
        Geoffrey SwensonApr 27, 2021

        A properly designed stylesheet tags an outer element with whatever the thing is. You then can assemble the object, and only light markup is needed for child elements because you can reach in with the stylesheet and control them. I had a job interview where they had "code standards" for doing css where you weren't allowed to nest tags to control them. Everything had to be top-level. Idiotic.

        When you are writing code with frameworks, it's easy to use the framework to be absolutely consistent about how the children are constructed, so the markup can be very minimal. It makes it easy to read when the css tags are only used when they actually control some behavior, and they read semantically rather than as named inline styles.

      • delanyo {Yokoyama} agbenyo
        delanyo {Yokoyama} agbenyoMay 7, 2021

        Color is not a brand, after all. And that could be a "hack". You don't try to win.

      • Kamel Labiad
        Kamel LabiadMay 12, 2021

        He seems to blame the tool rather than using a better methodology for writing a better style

      • Adam
        AdamApr 9, 2023

        It is more examples, that Tailwind will make your project doomed. It's very limited to strictly one style of UI and modifying it can be harder according to project design. Trust me, web development is not only greenfield project with fancy ui.
        Sometimes you need reusable components. It's hard to make it with Tailwind.

    • Kerry Boyko
      Kerry BoykoApr 20, 2021

      But that's just it.

      Search and replace will only search and replace based on text strings. Which is great if the only place you use "text-blue-500" is in components you want to change.

      That's the thing about utility classes - by definition, they're the same name everywhere you use them. So if you wanted to change "text-blue-500" to "text-red-500" in buttons -- and only buttons -- you'd have to find, and then manually look to see if it's a button before you replace it.

      On the other hand, if you have a .button class, or even better, a .branded-button class, you can just change it in one place.

      Find and Replace might be useful for changing variable names that are already fairly unique, such as from "my-button" to "branded-button" but it's not useful if you're trying to change, say, only some instances of "float-left" to "float-right".

      • James Thomson
        James ThomsonApr 20, 2021

        On the other hand, if you have a .button class, or even better, a .branded-button class, you can just change it in one place.

        But this is exactly how you should be using Tailwind anyway. If you are applying utility classes all over your html to make your buttons then this is akin to using inline styling. The power of tailwind is that you have an entire set of utility classes that allow you to make small tweaks on the fly because your designer wanted this specific button to have juuuuust a bit more margin-top and be fullwidth at certain resolutions, but you can also continue writing CSS as normal.

        I see Tailwind as a utility. It's not there to replace CSS, but compliment your workflow so you can get on with building components.

        Anyway, judging by your article and your replies in the comments you've made up your mind about Tailwind and that's ok, but there are many developers that are in favour of it, myself included. Best of luck!

        • Kerry Boyko
          Kerry BoykoApr 21, 2021

          I'm sure that you could use Tailwind that way, but at that point - why not just use small tweaks in inline styles instead of using Tailwind's classes? Inline styles also have the advantage of being higher CSS priority than class definitions, so you get exactly what you want right away.

          But then again, the problem with "if you use it this way" arguments is that they're different from "if you use it as intended." You can see from the Tailwind's own documentation that the intended purpose is to replace CSS.

          I'm not saying that utility classes aren't useful. I'm just saying that they shouldn't be used for everything. And they certainly shouldn't need all the tooling overhead that comes with tailwind.

          • Weekly Typed
            Weekly TypedApr 23, 2021

            I don't know why you keep saying this is not how Tailwind is intended to be used. The page you linked to is titled "Utility First". I infer that to mean the expectation is you start with utilities, and move to something else if you need it. Practically every word on that page seems to back up that inference.

            Further down the page is a section titled "Why not just use inline styles?" which explains what they see as the advantages of utility classes over inline styles. You didn't even acknowledge their reasoning in your article.

            The section after that one is "Maintainability concerns". This is where they expressly state that using apply to group styles together is, actually, using it "as intended".

            Again, it seems clear to me Tailwind's intention is you would build styles using utility classes first. After some point, they completely expect you to group at least some of those utility classes into a "bigger" class. You seem to think this grouping completely negates the benefits of using utility classes, and that you might as well write it in CSS.

            The documentation page that discusses this in particular is Extracting Components.

            I'm always wary when somebody says a newer syntax is "hard to read". It's definitely possible to write code that is hard to read. But how can you say it's hard to read when you've spent years training your brain to parse some other syntax. Readibility is subjective with things like this.

            For example, I found the example line in your article pretty easy to read. The purpose of md:h-32 and lg:h-64 are actually more obvious to me than the media queries. But I do agree the long horizontal line harder to read. But you don't have to do it that way.

            I like your analogy of using single letter variables. But I don't think it's the same thing. These are just short forms of CSS properties. They are clear and documented.

            I'm not sold on Tailwind myself. But if your conclusion is that it "provides no value", I don't think you argued it that well.

            • Kerry Boyko
              Kerry BoykoApr 24, 2021

              I don't know why you keep saying this is not how Tailwind is intended to be used. The page you linked to is titled "Utility First". I infer that to mean the expectation is you start with utilities, and move to something else if you need it.

              Eh... If that is your interpretation of Utility First, then I can't fault it.

              It wasn't mine, for a number of reasons, but you may have caught me out on an assumption I didn't know I was making.

              See, I thought that "Utility First" was referring to a coding philosophy, much like the philsophy of "Mobile First" -- you code for the mobile site first because the mobile site will always work on the full web-page, but not necessarily vice versa.

              Mostly, though, the reason why I don't think your interpretation is correct (Start with utility classes, then move away from them) is because almost every example on Tailwind's site is about how you can convert from semantic classes and CSS/SCSS to Tailwind Utility classes. If anything, Tailwind seems to suggest that CSS is a pain point that needs to be resolved and that utility classes are the solution.

              I agree that Tailwind might have use with rapid prototyping, but there's no real instruction on how to move from rapid prototyping to final product - You write Tailwind, you distribute Tailwind.

              I'm always wary when somebody says a newer syntax is "hard to read". It's definitely possible to write code that is hard to read. But how can you say it's hard to read when you've spent years training your brain to parse some other syntax. Readibility is subjective with things like this.

              I remember a similar argument from the author of Clojure about how Clojure (and other Lisp-like languages) were "hard to read." He said: "I don't know how to read German, that doesn't mean that things written in German are hard to read."

              But we can admit to ourselves that it is harder to learn certain languages than others, especially for an English speaker. And we can ask questions: Does this have a similar grammatical syntax? Does the language belong to the same family, does it have cognates and loan-words? Does it use the same sounds and tones? Is the alphabet the same?

              In the case of programming languages, we can ask similar questions:

              • Does the syntax provide valuable information about what it does? ('height' vs. 'h-', for ex.)
              • Is the syntax internally consistant (Not actually a problem with Tailwind, though PHP suffers from this.)
              • Does it introduce concepts not familiar to other languages? (C's lack of memory safety, Rust's 'ownership', Lisp's Polish Notation, and if you're coming from a dynamically typed language like JS/Python, static typing of TS/C#/Java/C++?)
              • Is it relatively clear to follow the structure of a program written in this language? (CSS is horribly bad at this, as priority order rules can get complex, latter styles overwrite former ones, and of course, there's the !important flag.)

              In this case, my criticism of Tailwind being "hard to read" deals primarily on the fact that the syntax is not expressive, and indeeds, chooses terseness over expressiveness. Back in the days of limited memory, sometimes a terse command was better than a long one, we still use "cd" for change-directory and "ls" for "list" in most Unix shells, but no such memory problems were at play here.

              It's also hard to read because it's embedded inside HTML, listed horizontally, rather than vertically. Now I'm not saying that it would be as hard to read as if we did styles in PDoublePrime but compared to the default of regular CSS, it makes it hard to read. Additionally, since you're no longer adding your own semantic class names to your HTML, it can be hard to tell by looking at the source exactly what element in the HTML code you're actually looking at when you debug it.

      • Patrick Nelson
        Patrick NelsonMay 10, 2021

        Re: @tofraley

        … because your designer wanted this specific button to have juuuuust a bit more margin-top and be fullwidth at certain resolutions…

        At the risk of taking sides (trying not to as I don’t understand TailwindCSS enough), I will say this: Usually when I encounter situations like this, I’ll bring it up to the designer. When that happens, at least in our case, it’s usually a misunderstanding (but not always). For example:

        1. They have an outdated set of components in their PSD’s, or just out of sync, etc.
        2. They actually intended for us to change this site wide (and not just this one button)
        3. In some rare circumstances they really did this as a one off (and if that’s the case, it’s good to have that clarity so we can built it that way with intent).

        Only pointing this out since, on the development side, all too often I’ve found developers simply matching the comps precisely without first ensuring that the change was intentional and (in this case, accidentally) creating one offs that ultimately weren’t really intended. 😊

    • Philip M. Gollucci
      Philip M. GollucciApr 20, 2021

      That's not true, you can use 'primary', 'secondary', etc.

      tailwindcss.com/docs/customizing-c...

    • Mario
      MarioApr 21, 2021

      We do we need constant values if we have search and replace...

      • imedacf
        imedacfApr 24, 2021

        Then don’t use functions at all

    • Nieuwe Pixels
      Nieuwe PixelsApr 25, 2021

      Not the point though. The point of CSS ,and/or SCSS for that matter, is too make styling more structured. If you need to do mass search/replace that might be a first cue.

      Naming it primary, secondary ect. would be a way to go instead.

    • Tanzim Ibthesam
      Tanzim IbthesamApr 26, 2021

      Use @apply and use same style everywhere. In react Vue we use components so we can just change style in one Component and it would work elsewhere.

    • Ashley Sheridan
      Ashley SheridanApr 26, 2021

      If you're relying on find/replace tools to make hundreds or thousands of edits to your codebase because of a change like this, it's still a problem. Everyone has seen (or caused) a scenario where a find/replace has gone wrong and replaced the wrong thing by accident, e.g. replacing "Arial" with "ArialBold", but accidentally creating instances of "ArialBoldBold" because your find-fu was off.

      However, if the code was following DRY principles, there would be very few instances that needed to be changed, so would be far more likely to be handled better.

    • Réda Housni Alaoui
      Réda Housni AlaouiMay 7, 2021

      The whole issue with the frontend community, in one comment. Well done.

    • David Hellmann
      David HellmannMay 7, 2021

      When you have a Button comp… Easy. Maybe variant:red is not a good approach. variant:primary

      problem solved. works also for all other comps. Don’t see the problem here from the author.

    • robvirtuoso
      robvirtuosoMay 8, 2021

      if only all developers were careful enough to use search and replace responsibly

    • Ahmadou Waly NDIAYE
      Ahmadou Waly NDIAYEMay 8, 2021

      The author was referring to the number of code changes.
      With standard CC, you have to do the change in just one place.

    • Alun Rowe
      Alun RoweMay 8, 2021

      You assume you want to replace all instances of text-blue-500

    • Thomas
      ThomasMay 10, 2021

      If only this was possible and such an easy change, you can't replace every instance of this in your app, what if it applies only to buttons/etc.

    • raydot
      raydotMay 12, 2021

      @Ranieri Althoff, if you have never introduced an error via search-and-replace I salute you for your charmed life as a developer!

    • Ebuka Ifezue
      Ebuka IfezueOct 27, 2021

      Lol I've been seeing hate articles with things that are non existent problems

      And besides if you are using a js framework or in my case laravel components it's as easy as changing one file

    • CaliViking
      CaliVikingJun 11, 2022

      @rsa - I think you have summarized why using Tailwind is a bad idea. You have ended up creating CSS that describes the text color blue, not what you want your style for a particular element to look like.
      There may be places where I want to continue using "text-blue-500" in other styles.

    • Luis Martinez Suarez
      Luis Martinez SuarezSep 27, 2022

      Damn... I wish we had:

      • Search and replace

      • The ability to use alias for colors, such as text-primary-500

      • The ability to abstract groups of tailwind classes into its own class. For example, with a keyword called, I don't know, @apply or something

      Too bad we don't have any of those things and thus obviously by direct deductive argument Tailwind sucks...

    • Adam
      AdamApr 9, 2023

      Yeah, because everybody want to use find/search every time when the want to change something in all places xD

    • Nhlanhla Lucky Nkosi
      Nhlanhla Lucky NkosiMay 7, 2023

      Search and replace still means you’re changing multiple things. More changes mean more chances of things being misaligned and it requires more testing. On an enterprise system, this increases the regression cost.

  • Ben Sinclair
    Ben SinclairApr 20, 2021

    I agree with all of this, and have been mulling over making a post about it for a while.

    • Alex Layne
      Alex LayneMay 10, 2021

      Save yourself the trouble and don’t. You too will sound like a clown.

  • Geoffrey Swenson
    Geoffrey SwensonApr 20, 2021

    Bootstrap and Material Design are also both utter messes of applying way too many tags to way too many elements. I prefer to write my own cleaner more terse styles. Tailwind just is even worse but I haven't had to use it thankfully.

    With this kind of overelaborate markup the stylesheet turns into a gawdawful warring mess of !important and even worse ng-deep messing up other devs pages especially because the backend devs that big companies tend to hire to do front end work seem to be incapable of using their own elements, creating simple reusable styles, or cloning well done markup from other pages and think that building a page is sort of like assembling tinkertoys without having to concern themselves at all with the messy art of design.

    • Archonic
      ArchonicApr 21, 2021

      If you're non-stop appending classes to get what you want, then sure, it can be a bit messy. I've found Bootstrap + a small amount of custom css with @extend to be great. I started making sites like that in 2012 and haven't looked back. Rebranding is super easy just by changing some variables and fonts.

      • Geoffrey Swenson
        Geoffrey SwensonApr 25, 2021

        In my last project idiot devs were using Bootstrap and Material design tags for different purposes on every page. It would have been better for the project if someone that actually knew what they were doing had written simpler styles and templates for all the common elements and they were almost always overriding things with the stylesheet many times with inline styles for all the framework items they were misusing. Every single page had elements common to other pages that were laid out differently and badly.

        I was the only one in the entire project that was writing comprehensive reusable styles and using for loops for repeated elements and I was making some headway in that the clients were liking my pages and not so much the dreck they were doing, but I got fed up about the massive unpaid overtime and took a different job. I still think bootstrap and Material design are barking up the wrong tree. They are too complex.

        As an example I just started a project in VueJS 3. I needed controls so my first library that I tried had utterly beautiful looking controls but when I installed it the compiler warned me that it was making my bundles too big. And looking further it was a big camel designed to get its nose into your tent and then force you to pay $900 per developer to use a designer tool they wrote to handle the massive complexity of the whole thing.

        I found a open source implementation of the multiselect I needed written in native Vue, with maybe 80 simply named css styles only 8k gzipped, easy to modify without a tool, which is the right way to build things.

        • Archonic
          ArchonicApr 27, 2021

          Any framework can be abused or misused through laziness/ignorance. I think plain CSS is actually the most susceptible to abuse. Freehand tools are the most flexible but with no standard laid out, most people will just end up making a huge mess over time.

          I understand the argument that Bootstrap is heavy but it's only JQuery that makes it heavy and BS5 will get rid of that. If a project doesn't need a component, just don't include it. Perhaps I have heart shapes glasses because I prefer a standardized look and feel over something unique but I'm going to keep reaching for standard libraries that let me get a front-end done in days instead of weeks.

          • Geoffrey Swenson
            Geoffrey SwensonApr 27, 2021

            I still think Bootstrap is a stunningly awful POS. I have been forced to use it on three projects now, loathe it. I can write my own stylesheets way better. There are a few good ideas in there, such as the font icons, but the whole idea of putting ten tags on every element and the idiotically meaningless names of the grid controls can just go somewhere the sun doesn't shine. It doesn't save you time, it makes things harder.

            I create my own standardized look and feel.

            All of the projects where I loathed Bootstrap were using modern frameworks. It has nothing to do with jQuery, it has to do with the terrible metaphors Bootstrap uses.

            • Archonic
              ArchonicApr 27, 2021

              Strong words. You aren't forced to use 10 classes everywhere. You could come up with one class which extends those 10 classes and then use one repeatable class, same as any compiled CSS. I think of BS and all the other frameworks as just time-saving utility and for me it's always done a good job of that. I don't honestly know how it could possibly make things harder unless your always overriding it, which is a miss-use.

              • Geoffrey Swenson
                Geoffrey SwensonApr 29, 2021

                I wasn't the one overriding it. But the stylesheet was a mess of overrides nevertheless. I've never seen anyone compile the Bootstrap classes into one class, they were using them everywhere with multiple classes on every object.

                The problem is that it becomes very difficult to see where some unwanted style attribute comes from. I also don't even want to understand how the grid classes work, because the names don't make any sense whatsoever.

                What I really can't stand is how large companies hire back end developers that think that using a CSS library like this is a substitute for actually writing a well conceived ui. They pile on the various containers and objects and get something hugely inconsistent with layout anywhere else. I have written very large applications, and I didn't need a third party library to do it. I have in the past copied just the bootstrap style icons into a project but not used anything else from it. It's a style of markup I strongly disagree with.

  • Trevor Waters
    Trevor WatersApr 20, 2021

    These concerns are addressed by them

    tailwindcss.com/docs/utility-first

    • Kerry Boyko
      Kerry BoykoApr 20, 2021

      Actually the first example on the page shows EXACTLY why I don't like Tailwind.

      Take a look at the first example of the code. I don't know if you can use markdown in the comments. It looks like a huge amount of code, compared with the Tailwind example below it. But think about it. Is it really less code?

      The second example - the tailwind example, is pretty much the same length as the HTML in the original example. All that CSS code is still there, it's just moved to a place where you can't readily see it, examine it, look for bugs in it, etc. You could get the same effect just by putting the CSS in a seperate file...

      Additionally, the CSS they use to demonstrate the "complexity" of CSS is... needlessly complex. I'm not saying it's not passible - it'd pass code review if it was in my wheelhouse - but there are better ways to structure it.

      First, I'd use CSS variables, I'd use SCSS if possible, and I'd use properties to make organizing it a lot more paletable.

      So, my solution would be:

      <div class="chat-notification with-box-shadow">
        <div class="logo">
          <img src="/img/logo.svg" alt="ChitChat Logo">
        </div>
        <div class="content">
          <h4 class="title">ChitChat</h4>
          <p class="message">You have a new message!</p>
        </div>
      </div>
      
      Enter fullscreen mode Exit fullscreen mode
      /* constants */
      
      $white: #fff;
      $color-chat-title: #1a202c;
      $color-chat-message: #718096;
      
      /* utility */
      
      .with-box-shadow {
        box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
          0 10px 10px -5px rgba(0, 0, 0, 0.04);
      }
      
      /* semantic */
      
      .chat-notification {
        display: flex;
        max-width: 24rem;
        margin: 0 auto;
        padding: 1.5rem;
        border-radius: 0.5rem;
        background-color: $white;
        .logo {
          flex-shrink: 0;
          > img {
            height: 3rem;
            width: 3rem;
          }
        }
        .content {
          margin-left: 1.5rem;
          padding-top: 0.25rem;
          .title {
            color: $color-chat-title;
            font-size: 1.25rem;
            line-height: 1.25;
          }
          .message {
            color: $color-chat-message;
            font-size: 1rem;
            line-height: 1.5;
          }
        }
      }
      
      Enter fullscreen mode Exit fullscreen mode

      Doesn't <div class="chat-notification with-box-shadow"> look a lot better and easier to read (not to mention tells you WAY more about what the component actually is) than <div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4">?

      In fact, how is a programmer who has to work with the HTML supposed to know that <div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4"> is your chat notification? If you've got a bug in your chat notification, it would be awfully useful if programmers could find it to know where to start looking!

      • Søren Kottal
        Søren KottalApr 21, 2021

        A few months in you need to add another component. Designers says it should look completely like your chat-notification. What do you do? Duplicate the styles, or rename your "semantic" class to something more generic. (By the way, class names is not and can not be semantic .chat-notification is not more semantic than .with-box-shadow).

        And where is the seperation of concerns / html is for content arguments when doing ".with-box-shadow" classes?

        • Kerry Boyko
          Kerry BoykoApr 21, 2021

          What do you do? Duplicate the styles, or rename your "semantic" class to something more generic.

          Naturally I choose neither.

          First, let's look at plain CSS, no preprocessors, no CSS-in-JS, just the tools we've had since the beginning of the century.

          This is actually a very good use case for writing a utility class like "with-box-shadow" -- when you have reusable code. It doesn't remove the need for semantic classes to tell you what something is and keep one component separate from another.

          And where is the seperation of concerns / html is for content arguments when doing ".with-box-shadow" classes?

          I'll admit that having 'with-box-shadow' does violate separation of concerns, and if I really want to be a semantic stickler, using just standard CSS and HTML, I'd have to rewrite the same code in multiple places, duplicating, as you said, the code from one semantic class to the other.

          I'm not a semantic stickler, and in this case, wrote a utility-class because it A) made sense, B) was limited, C) there were no better options. As I said, I'm not opposed to utility-classes. I'm opposed to a philosophy that all classes should be utility classes.

          But thank goodness that in the real world, there are better options - preprocessors and CSS-in-JS! Either allows you to reuse bits of code more idiomatically. (and use functions, too, making it even more powerful.)

          If I'm using emotion/css or another CSS-in-JS solution, for example, I wouldn't have a with-box-shadow class. Instead, I could extract the code to a variable: 'boxShadowCSS' or '@mixin hasBoxShadow' That new variable could then be interpolated by both .chat-notification and .new-component's own definitions, like so.

          /* SCSS */
          @mixin with-box-shadow {
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
              0 10px 10px -5px rgba(0, 0, 0, 0.04);
          }
          .chat-notification {
            @include with-box-shadow;
            /* rest of code */
          }
          .new-component {
            @include with-box-shadow;
            /* rest of code */
          }
          /* HTML : 
            <div class="chat-notification"/>
            <div class="new-component"/>
          */
          
          Enter fullscreen mode Exit fullscreen mode
          /* CSS-in-JS (emotion/css) */
          import {css} from 'emotion/css';
          
          const withBoxShadowCSS = css`
             box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
              0 10px 10px -5px rgba(0, 0, 0, 0.04);
          `
          const chatNotifictionCSS = css`
            ${withBoxShadow};
            ${/* rest of code */};
          `
          const newComponentCSS = css`
            ${withBoxShadow};
            ${/* rest of code */};
          `
          export const MainComponent = () => <>
            <div className={['chat-notification', chatNotificationCSS].join(' ')}/>
            <div className={['new-component', newComponentCSS].join(' ')}/>
          </>;
          export default MainComponent;
          
          Enter fullscreen mode Exit fullscreen mode

          Tailwind wouldn't actually solve the problem, the code would just end up looking like this:

            import tw from 'twind'; 
          export const MainComponent = () => <>
            <div className={tw`p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4`}/>
            <div className={tw`p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4`}/>
          </>;
          export default MainComponent;
          
          Enter fullscreen mode Exit fullscreen mode

          To which I have to ask - if the designer says that they no longer want it to be exactly alike, that they want the new component to not have a drop-shadow, which one of those "shadow-md"s are you going to delete?

          • Søren Kottal
            Søren KottalApr 22, 2021

            So you did actually duplicate the code into .chat-notification and .new-component.

            I think a lot of the knee jerk reactions regarding seperation of concerns comes from something we all learned was the right way, but never really adhered to anyway.

            As you see yourself, .with-box-shadow is not a good way to seperate concerns, neither is .col-sm-4, .card, and other often found classnames.

            Tailwind to me is about accepting the fact, that completely seperating concerns between html and css, is at best an academic approach, and in most cases completely unnecessary for most projects. Often adhering to this is creating a much larger burden on the developer for little to no gain.

            The author of Tailwind, Adam Wathan wrote this article about utility css and seperation of concerns. , that I really think you should read.

            I'm not trying to concince you into using tailwind (or other utility first methodologies for that sake), but at least acknowledge that this methodology works wonders for a lot of people. At least you could append "for me" to your title.

            To me, Tailwind removes complexity and adds function. My team now has a well documented vocabulary for building nearly anthing. Before that we had CSS scattered all around (thats not CSS' fault, though 😉), and different naming strategies across different projects. A .card could be named .article, or .box (or something semantic) depending on the project, and the mindset of the developer implementing it first. In tailwind it's just utilities, and I can onboard a new developer to an existing project in no time, and never fear that a change in one place, breaks something completely different in another place.

            • Kerry Boyko
              Kerry BoykoApr 22, 2021

              So you did actually duplicate the code into .chat-notification and .new-component.

              If, by "duplicate", you mean, I created a const variable with the data, and then referenced that variable in two places... then yes, I guess I did.

              But isn't that the whole point of variables? Especially const variables? To make it so you don't have to type out the same thing multiple times?

              Tailwind to me is about accepting the fact, that completely seperating concerns between html and css, is at best an academic approach

              It's not an academic approach, it's a "best practice". As in - used in practice, not in theory. It's not academic at all. Using semantic-only class names is the best practice. A close second - a "second-best practice" if you will, is using utility classes sparingly. Using nothing but utility classes is a "worst practice."

              at least acknowledge that this methodology works wonders for a lot of people. At least you could append "for me" to your title.

              I think that the methodology might work for some people, but not for people developing professional quality software in a professional environment, for the reasons I've stated. If you want to use this in your solo side-project or hackathon app, go right ahead.

              Regarding Adam Wathan's article...

              I don't know what to tell you. The point he starts with "dealing with similar components" as a dilemma -- I get it. There is no way to do that without duplicating code in regular CSS.

              It's the limitation of the scripting language. It's like trying to write a function in HTML, you just can't, it's not built for it. CSS isn't built well for code reuse. I wish it was. So in order to solve these problems CSS preprocessors like SASS/SCSS were developed, as well as the myriad of CSS-in-JS solutions. It solves the problem of "not being able to reuse code" directly - by allowing you to set variables and functions so that you indeed can reuse code.

              I often feel like the goalposts keep shifting here. To clarify: Yes, I would rather take the problems with duplicated code in plain-CSS and keep semantic classes, than the myriad problems with Tailwind. However, all of the problems that Tailwind claims to solve already have been solved by other tools and they don't introduce the problems that Tailwind introduces.

              A metaphor: say that in the 1990s, the only way to build a house was to bang nails in with a flat rock (CSS). And then, around the mid 2000s, a really smart guy invented "the hammer." (Sass) It took adjusting, and you have to learn a new tool, but it did the job much better.

              Around the early to mid 2010s, another guy invented the nail gun (CSS-in-JS/Aphrodite/StyledComponents/Emotion, etc.). It worked even better... but it required power and a steady hand, and you had to be careful with it. It was (computationally) expensive too, so a lot of people stuck with the hammer because it was working fine for them. Which was okay. People would often use a manual hammer when the manual hammer seemed appropriate, and the nail gun when they seemed to need it. And all was good in the world of carpentry.

              Then in 2017, someone came up to the carpenters and said: "Hey, see what happens when I do this!" and starts hammering in nails with the butt end of a loaded revolver (Tailwind). Look at how much better this works at hammering in nails than banging them with a rock! It's like a miracle!

              "But it's a loaded gun. It might go off and shoot yourself"
              "Hasn't happened to me yet."
              "Why don't use use a hammer? Or a nail gun?"
              "I don't like hammers or nail guns."
              "I can understand why you might not, but even if you used a rock, that would be safer in the long run."
              "Ah, but a rock can end up marring the wood."
              "I'm not saying to use a rock. I'm saying that the hammer already solves the problems you have with the rock, but even the rock is a better tool for this than a loaded gun."

              • Mykolas Mankevicius
                Mykolas MankeviciusMay 9, 2021

                You do like your strawmen don't you?

                import tw from 'twind'; 
                export const MainComponent = () => <>
                  <div className={tw`p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4`}/>
                  <div className={tw`p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4`}/>
                </>;
                export default MainComponent;
                
                Enter fullscreen mode Exit fullscreen mode

                Imagine for a second that React could use components, I know it's not possible, but just imagine, and your strawman code would become like this:

                import tw from 'twind'; 
                export const MainComponent = () => <>
                  <ChatNotification />
                  <NewComponent />
                </>;
                export default MainComponent;
                
                Enter fullscreen mode Exit fullscreen mode

                If only React or any other js framework would have the concept of components. How beautifull the world would become, right? Maybe one day we'll be able to write code like this, but most likely not for years to come!

                And CSS isn't built well for code reuse. is also wrong.

                All the utility classes are there in the css file, once. And are being re-used by all these different components. Which makes the final css tiny, and those CSS classes, wait for it... re-usable. OMG, WOW, SUCH IMPOSIBILITY.

      • Mykolas Mankevicius
        Mykolas MankeviciusMay 9, 2021

        Imagine, just for a second that you put that code in to, wait a minute.... a component named ChatNotification? Wow all of the strawman arguments burn away!

        <div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4">
          <div class="flex-shrink-0">
            <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
          </div>
          <div>
            <div class="text-xl font-medium text-black">{{ title }}</div>
            <p class="text-gray-500">{{ message }}</p>
          </div>
        </div>
        
        Enter fullscreen mode Exit fullscreen mode

        Suddenly you don't need to parse all that CSS it's right there visible in the template. Sudenly you have context of what is what.

  • Ivo
    IvoApr 20, 2021

    I'm not very adept with CSS yet I still agree with a lot of what's being said there, mainly how unmaintainable (and unreadable and just plain ugly) it makes your HTML if you use it how much of their docs suggest.
    The parts I like about it is that is pre-defines sizes for a bunch of things in rem (m-x etc), that's it's easy to make something responsive or darkmode or whatever modifier by just adding a prefix and the typography add-on (makes it incredibly easy to style generated HTML so it looks nice).
    So I just use those parts to make my own classes with a mix of @apply and regular css becuase it's no problem to mix that.

    • Kerry Boyko
      Kerry BoykoApr 21, 2021

      You might actually be a good candidate for Tailwind, but not to use as intended.

      I make an argument that "if you use it this way" is not "if you use it as intended". What I'd suggest in your case is using it as "training wheels" to CSS. If there's something you can't figure out how to do in CSS, but you know how to do it in Tailwind, try using tailwind in your first draft to apply the styles you want, then go into your Chrome/Firefox element inspector to see how Tailwind's styles got translated to CSS, and replace the CSS. This actually seems like a really solid way to start getting better at CSS.

      Again, though, it's not used as intended.

  • Adam Crockett 🌀
    Adam Crockett 🌀Apr 20, 2021

    😎 never used tailwind because like every other flash in the pan including my own flash in the pan inventions, I always go back to Sass or Sass like things, because that's what I saw first. It's like the baby duck 🦆 sees it's mom 🦃, you only get one first impression and that's the one that sticks.

    • Adam Crockett 🌀
      Adam Crockett 🌀Apr 20, 2021

      "but you should, youl like it" to which I say, I like ducks

    • Kerry Boyko
      Kerry BoykoApr 21, 2021

      I've been coding HTML since the mid-90s. If I felt that way about everything I'd still be using <table> tags.

  • PuruVJ
    PuruVJApr 21, 2021

    If tailwind provided a ::after and ::before way, I'd even consider it worthy of being tried

  • Etienne Burdet
    Etienne BurdetApr 21, 2021

    I was about to write a piece like this (and I might do it anyways!). But I totally agree on the "does not solve problems it claims to" part. They claim to solve the naming problem, only to delegate it to single file components… where style is scoped so you don't need naming anyways.

    And I would be super concerned about maintaining it. Built of speed no doubt. But I moved away from bootstrap utility classes when I had to change some margins—but not all. Now why was this one m-4 ? Should I change it to m-3 ?

  • Alain D'Ettorre
    Alain D'EttorreApr 21, 2021

    I respect people who use it, but I think it is completely unnecessary and adds complexity on top of standard CSS without any convenience. You put a million inline-like classes on an element, then you either slam it into a component or try to move it to some SASS file. When in a SASS file, you then @apply not-so-configurable classes without any access to mixins, variables (both CSS or SCSS) etc. It makes no sense to me.

  • Leonard Kioi kinyanjui
    Leonard Kioi kinyanjuiApr 21, 2021

    you've just chosen your hill to die on

  • Michael E Conroy
    Michael E ConroyApr 21, 2021

    Not to mention the weight it adds to your HTML files by having to add a huge list of classes to your elements.

  • etcroot
    etcrootApr 21, 2021

    I mean you can still use tailwind and use the function @apply in the css and make class names with it? And with the newly introduced 'jit' mode it's faster than ever before to compile it

  • jacksoncool
    jacksoncoolApr 22, 2021

    I say if you don't like it, don't use it. If you like it, use it. Not everyone loves React, some Vue. Some vanillaJS. I use to use my own rolled up CSS. Then bootstrap with my own stuff. Then later I used Foundation and my own CSS. Personally, I like Tailwinds.

    Use what works for you and your team today and hopefully later in the future.

    And btw, I was one of those early 90s guys that started developing when Netscape 2.0 was so AMAZING (it was) and later used tables (HATED IT), so most of the stuff today is GOLD!

    • Kerry Boyko
      Kerry BoykoApr 22, 2021

      I say if you don't like it, don't use it.

      As personal developers, you should work with the tech stack that you like. As professional developers, we rarely get that option until we're at the level where we're making architecture decisions for the team.

      What I'm saying is: Even if you personally like Tailwind, you need to know how your decisions will affect the product and your team.

      The point of these criticisms of Tailwind (and other similar criticisms of other tech (Why Does PHP Suck is always a fun read), is that when we criticise these technologies harshly, we are explaining not why we don't like it but why team leaders and architects shouldn't choose this tech for their stack.

      For example, I don't like Java, but I can't make a compelling case to never use Java in enterprise applications. I really like Deno, but I can't make a compelling case to move our Node-based production over to the new platform. It's not about preference, it's about profession.

      Or more bluntly:

      Ralph Nader: "The Ford Pinto is unsafe at any speed"
      Ralph Nader's Comments Section: "If you don't like the Ford Pinto, don't drive it!"
      Ralph Nader: "You'll hurt yourself"
      Ralph Nader's Comments Section: "That's my right as an American!"
      Ralph Nader: "You'll hurt others!"
      Ralph Nader's Comments Section: "Shut up!"

      • Alex Layne
        Alex LayneMay 10, 2021

        As a professional developer, when we switched all of our new projects to Tailwind, everything got easier and more efficient for us. We don’t have time or resources to implement some ridiculously verbose CSS methodology like BEM. You’re effectively just saying “you shouldn’t use this because I say so” and frankly you sound like a clown to me.

  • c5n8
    c5n8Apr 22, 2021

    Tailwind is design system framework that is meant to be constrained and works best with ui component if you need abstraction.

  • Carsten Führmann
    Carsten FührmannApr 22, 2021

    I love your article since it confirms my own internal rant about Tailwind😉 One remark from the side: utility classes do have one advantage over inline styles you did not mention: These days, it's best to have your site send "Content Security Headers" to avoid accidental execution of dangerous 'code'. When you use inline styles, you have to taint your content security headers with the ugly "stye-src: unsafe-inline' directive - which also opens up your site to nasty styles injected by others.

    But that's no argument for Tailwind - there are better ways.

  • Alex Janke
    Alex JankeApr 22, 2021

    Oh boy did you get some reactions to the post.. I totally haven't read all the comments so I might just rephrase some other comments in my own words and maybe add my own two cents while I'm at it.
    First of, don't use apply. Don't. I'd deny any pull request using @apply. Horrible feature. Yuck.

    From skimming through the comments I didn't see the point of standardization though. You can ignore all extra work of making sure all your devs in your team use the same kind of class-namings. To BEM or not to BEM, all these decisions go out the window, reducing extra time needed in planning that is better used to actually get to work.

    The example you have in your section "It's hard to read":
    How are they any different if you put the code into a component? All tailwind really helps me with is to not get fuzzy and build my own broken diy-css-framework over the time. It stops me from doing stupid things like getting into the habit of writing bootstrap-esque classes á la .card .card-title .card-body and so on. Instead of writing several classes myself now I write more components and think about making my project more modular, increasing reusability while maintaining a single source of truth. Now you might say "but I can have a source of truth too in my .css file". Sure. But why would I go through all the hassle and time to slowly write all the css classes myself that are literally right there from the get-go?
    Convenience and maybe a good portion of laziness? Yup, absolutely.

    I'd probably just don't use it if there is some crazy specific task from a client where you can see right away that you're going to rewrite 90% of the tailwind config anyways. Overall it's just crazy fast to get websites done with tailwind while staying consistent in your markup, especially in prototyping stages.
    So all that's left is probably to look at it by a case by case scenario and decide what tool to pick for the job. As always.

    • Kerry Boyko
      Kerry BoykoApr 23, 2021

      First of, don't use apply. Don't. I'd deny any pull request using @apply. Horrible feature. Yuck.

      I agree. Not that I don't think you shouldn't bundle related CSS properties together into reusable classes, but that the whole point of Tailwind is to avoid that type of composition altogether. I may not agree with Tailwind's philosophy, but I don't mind pointing out as part of it's criticism when it's being philosophically inconsistant.

      You can ignore all extra work of making sure all your devs in your team use the same kind of class-namings. To BEM or not to BEM, all these decisions go out the window, reducing extra time needed in planning that is better used to actually get to work.

      Weirdly, "making sure all devs use the same class namings" is not really a concern that I have. I mean sure, it's a good thing to aim for, but it's only really a "must have" if you're using an unscoped global .css file for styling. Most of the work I've done has been in Vue or React; which means I'm either using Vue's <style lang="scss" scoped>, CSS Modules: "import 'myComponentStyle.scss", or CSS-in-JS: "const myComponentCSS = css\" (which probably won't show up right because of markdown not interpreting backticks

      I suppose if your team is operating on one big global .css file (instead of using CSS modules or CSS-in-JS) you have to make sure it is using the same naming conventions.

      But for the most part, it's more important to me that class names are unique and descriptive of content rather than follow a certain format, so that they can be easily searched for in the source code of the finished HTML (for debugging) or understood by the rest of the developers on the team.

      One of the patterns I'm seeing is that people who really seem to like Tailwind point out how much more useful it is than CSS, and don't seem to have a whole lot of experience or willingness to try CSS-in-JS or pre-processor (SCSS) solutions.

      It stops me from doing stupid things like getting into the habit of writing bootstrap-esque classes á la .card .card-title .card-body and so on.

      I have no problem with utility classes, used sparingly. Ideally I'd prefer SCSS mixins or resuable CSS-in-JS code compared to them, but what's wrong with that?

      mixin card {
        &.title {
          /* css */
        }
        &.body {
          /* css */
        }
      }
      .recipe {
        @include card;
      }
      .captioned-photo {
        @include card;
        & img {
           /* css */
        }
      }
      
      Enter fullscreen mode Exit fullscreen mode
      <div class="recipe">
        <div class="title">title</div>
        <div class="body">body</div>
      </div>
      <div class="captioned-photo">
        <div class="title">title</div>
        <img src="foo"/>
        <div class="body">body</div>
      </div>
      
      Enter fullscreen mode Exit fullscreen mode

      But why would I go through all the hassle and time to slowly write all the css classes myself that are literally right there from the get-go?

      This is a compelling argument for a framework like Bootstrap, but not one like Tailwind.

      One of the problems I have with tailwind is how many of it's classes - something like 99% -- though I haven't done the actual math, I'm pretty sure that's the right ballpark, give or take 1% -- are just one or two lines of CSS.

      "p-8" is just "padding: 1.5rem;". "rounded-full" is just "border-radius: 9999px".

      I did go through and identify about nine tailwind classes (out of how many hundreds?) that DO actually provide some convenience and am rewriting them in my own utility class library.

      Overall it's just crazy fast to get websites done with tailwind while staying consistent in your markup, especially in prototyping stages.

      By all means, prototype away, but I wouldn't recommend it if you're dealing with end products meant to be delivered to the product owner.

      • Alex Janke
        Alex JankeApr 23, 2021

        I honestly don't use it as much as my text might suggest but I can see the appeal and tried to find some points to make you maybe see them from a different point of view :D

        but I wouldn't recommend it if you're dealing with end products meant to be delivered to the product owner

        This caught my eye because I honestly never worked in a situation where I hand over code to another owner and I mostly work on internal products. The rare SaaS things I worked on were in good ol' SCSS though.
        What would be interesting to see is the type of projects people work on using Tailwind. Is it a lot more agency-type of projects, internal sites (as in admin tools) or SaaS?

  • Daniel Kaiser
    Daniel KaiserApr 22, 2021

    I haven't used. But I do believe solutionism is a problem in the dev community. Either making solutions to problems that don't exist OR brining a tank to a knife fight

    • Rick Mills
      Rick MillsApr 23, 2021

      I think it's pretty clear it provided a good solution to a problem, otherwise the company formed on the back of it wouldn't be multi-millions in profit, and it wouldn't have rocketed in popularity past Bootstrap.

      Some of the arguments in the article are valid, some are the typical ones we often see from people who've not taken the time to use it (throwing up a 1 page app isnt even close enough to fully appreciate what it can do).

      The common arguments such as bloated html and duplication of code often just highlight how much people totally misunderstand Tailwind.

      • Kerry Boyko
        Kerry BoykoApr 24, 2021

        I think it's pretty clear it provided a good solution to a problem, otherwise the company formed on the back of it wouldn't be multi-millions in profit, and it wouldn't have rocketed in popularity past Bootstrap.

        The #1 seller of hamburgers in the United States has been, for years, McDonalds. Does that mean a Big Mac is the epitome of high cuisine? Does it even mean it's healthy?

        Millions of people use PHP, too. That doesn't make it a good programming language, and it doesn't make it a good idea to start a new team project in PHP.

        I think you're falling into a rhetorical trap here: a bandwagon argument. A viewpoint can be in the overwhelming vast majority and still be wrong. The popularity of a position doesn't have impact the objective truth of it.

        • Ashley Sheridan
          Ashley SheridanApr 26, 2021

          Hey, let's not be putting PHP in the same bucket as Tailwind! :P

          But absolutely agree, popularity doesn't equate to worth of a project/language/etc. Just look at some of the projects on npm like is-odd (and its counterpart is-even which relies on the former). Thousands of downloads per week to avoid modulus math in our code and make things look "nicer" and more "functional".

          Tailwind might have solved a problem, and that's logical to assume so (I've not seen what that problem is, but that doesn't mean it didn't exist), but it also creates its own problems, as you've pointed out. What we need to be doing is more of this, more questioning on our tools, and looking at alternatives that solve the problems in better ways without creating more issues.

          • Kerry Boyko
            Kerry BoykoApr 26, 2021

            I may be prejudiced on my view of PHP, mostly because I once took a job... an overseas job, too... where the job listing was for a JS engineer, the job interview talked about JS experience, the take-home test was to write a JS front-end (React), the technical interview was conducted in Javascript, and the job title was for "Front-End Engineer"... and then I open up the codebase, and it's 95% PHP.

            I explored all possible avenues -- transferring to a different department -- putting transition to Node on the roadmap for the next quarter -- everything. No, apparently I was now the PHP guy on the team.

            I lasted two and a half days, and started packing my bags, getting ready to move once again.

  • Ryan
    RyanApr 22, 2021

    I agree with pretty much everything in this article yet I also find myself really liking the the naming conventions tailwind has used. For example, I find the media query prefixes to be very intuitive.

    I think the middle ground here is to use @apply all over the place despite tailwind's documentation recommending against it.

    All of those classes really make no sense.

  • Brian M.
    Brian M.Apr 22, 2021

    I love tailwind. I love the absolute tiny css file that goes along with it (when purged). I love that my boss will not mess up the rest of the site by editing a css style for his pet project page. I love not having to invent names for css classes. I love extracting tailwind classes to re-usable components.

    • Kerry Boyko
      Kerry BoykoApr 23, 2021

      I love that my boss will not mess up the rest of the site by editing a css style for his pet project page.

      You have bigger problems than I can deal with here.

      I suppose in some cases, tailwind would be an improvement if your boss can go in and edit your company's css file for a project page. But then we're not exactly talking about best practices, are we?

      • Brian M.
        Brian M.Apr 23, 2021

        You can replace the word "boss" with "others".

        • Kerry Boyko
          Kerry BoykoApr 24, 2021

          Still doesn't change the problem.

          It seems like the problem is one of scoping, and tooling though, now that you mention it.

          First, it seems like you're editing a global .css file. Now, whether it's SCSS, CSS Modules w/ a bundler (Webpack? Rollup?) it's... rare these days for there to be one universal CSS file precisely because web development has gotten much more complex. The output might be a single CSS file - that's the point of a bundler after all - but the input shouldn't be.

          One of the key things you can do with CSS (and it's even easier in SCSS) is to introduce scoping.

          So, let's say that you have a pet page.

          All you have to do is, in the root of that pet page (whether it's

          or or whatever...) is add )

          You can then write styles that apply only to that pet page.

          /* CSS */
          .pet-page h1 {
              font-family: Lobster, Comic Sans, Sans;
          }
          .pet-page h2 {
              font-family: Lobster2, Lobster, Comic Sans:
          }
          .pet-page .call-to-action {
              color: pink;
              border: 3px dotted pink;
              padding: 5px;
          }
          

          It's even easier in SCSS

          /* SCSS */
          .pet-page { 
            h1 {
              font-family: Lobster, Comic Sans, Sans;
            }
            h2 {
              font-family: Lobster2, Lobster, Comic Sans:
            }
            .call-to-action {
              color: pink;
              border: 3px dotted pink;
              padding: 5px;
            }
          }
          

          This is the power of CSS Combinators, one of the things you lose with Tailwind.

          • Brian M.
            Brian M.Apr 25, 2021

            Sorry, I guess I should have been clearer. I understand scoping, components and most modern css best practices. I used to do agonize over all that with sass/less/postcss - code splitting across files where it made sense, components, namespace scoping, BEM and other methodology experiments. All with some form of build using npm/gulp/grunt/bundlers/etc. Now we just tailwind and don't really need the other stuff. It works great for our team.

  • IceTrooper
    IceTrooperApr 22, 2021

    What about if you're using Tailwind with some framework like React when you're building components and use Tailwind in those components? I mean, instead of replacing 123 occurrences 'blue-color' you just replace it in one place, in the button component.
    After all, is Tailwind just a replacer for simplifying CSS?
    I'm not defending Tailwind. I know what it is, but I've never use it. Thank you for your article (like you see from other comments [still valuable] it's controversial) but while I was reading I wondered if all disadvantages described in the article are in context of web development without frameworks like react? Because Tailwind with React could be just a replacer for more difficult CSS?

    • Kerry Boyko
      Kerry BoykoApr 23, 2021

      That is a good point, and in theory, that could work. I don't think that when the rubber hits the road, though, it will.

      A really well organized React/Vue project will probably be like that. You have a roughly 1-to-1 ratio of "components" to "css classes". You style only in "dumb components" (i.e., stateless, takes only props), and if it's not "one className entry per component", it's at least really close.

      It eliminates many of the problems I've pointed out about code-reuse, and having to change class names in multiple places.

      But it doesn't eliminate the problems with debugging. If you try to inspect an element in the browser - that is, after it's no longer a component, and now lives as part of the DOM, you can't really identify what the component is by class anymore. It makes it harder to identify the root cause of the bug, which increases the Mean Time To Repair.

      It also doesn't eliminate the problems with having to learn new Tailwind syntax, with prioritization (if you were to give an element "h-12 h-8", or "h-8 h-12" which height would apply first... and how would you know unless you looked at Tailwind's sourcecode to see what got defined last?)

      And it certainly doesn't account for the scenario when the React or Vue app you're working with doesn't have a very "atomic/molecular/organism" structure at all - but is a mishmash of big components, small components, components that depend on Vuex, components that have props reassigned to internal state which on-change run a callback prop... (Ugh!)

      What I do think might be useful is using something like the Twind library to rapidly prototype what you want your final CSS to look like, but then taking the CSS outputted by Twind, copying it from the browser inspection, and plopping it right back in to something more long-term like emotion/css.

    • Ashley Sheridan
      Ashley SheridanApr 26, 2021

      How far down do you go with turning things into components though?

      For example, imagine creating a very simple alert modal component. This contains a message, and a button. Now, I've done this exact thing, and the button is just an HTML <button>. I could embed a button component into it instead to mitigate the problems of Tailwind, but that seems like it's going too far in the direction of breaking things into the smallest possible parts. There's a point at which something becomes too small to separate out into it's own component/class/modules/etc. There's a balance between making the code readable and logical, and also ensuring that it's comprehensible by the human who is managing it.

      Should the modal text be its own component too, as it contains styles very specific to a modal. It needs to be re-used across all of the other modals (prompts, confirmations, password queries, etc), and we want to avoid the need to be making multiple find/replace changes that Tailwind might force us to make otherwise.

      Tailwind would allow us to do this in a more sensible manner, but it's not generally how TW projects appear to be done the majority of the time (going from the numerous articles and code examples in Git repos), and it's something that was already very much possible in vanilla CSS, let alone the many pre and post-processors for CSS that have existed and been in use for many, many years successfully.

  • Jon Telles
    Jon TellesApr 23, 2021

    You're getting a lot of pushback here but I completely agree with you. It's pretty baffling to me how popular it is, but I LIKE CSS so maybe that's the difference.

    Not trying to throw shade but many of the people I see favoring Tailwind admit that they're bad at CSS or actively hate it.

    At this point I know CSS very well so it seems like much more work to fiddle with abstracted utility classes and learn the "Tailwind way" of doing something, rather than the CSS way...which I know isn't going anywhere and has standards.

    • Kerry Boyko
      Kerry BoykoApr 23, 2021

      Oh, and there's a lot to hate about CSS.

      The standard names can indeed be confusing. Dealing with priority -- i.e., what styles overwrite other styles -- can be problematic as well. In the original spec, there was no support for variables, which made it impossible to reuse code from class to class, and even today there isn't support for functions.

      And yet, we continue to use it -- and our dependency on it grows, because while nobody likes the CSS standard, nobody can agree on anything that can replace it. The best we have are tools that transpile to CSS.

      This is why I really do think that something like native support for SCSS files should be a priority of whatever muckety mucks are in charge of WebKit. But then again... I don't see that happening anytime soon when the existing solutions are good enough.

  • Mario Kober
    Mario KoberApr 23, 2021

    I fully agree. It makes, code ugly and I cannot imagine a case where this makes me faster. I have a few utility classes and a nice grid I made so I can change collums, padding and positioning while writing HTML und the real look is made in CSS. But yeah, people are using what they want. Not all are thinking that code should be minimal and nice.

  • Baptiste Crouzet
    Baptiste CrouzetApr 23, 2021

    I agree it's not readable at all. Styles and HTML are not separated anymore it's sad.
    And a question is to answer, which order for theses classes ? Not all developpers will order it in the same way...
    The people I know using tailwing are generally bad in CSS or too lazy to write it.

    Have a look to RSCSS -> class names will have a real utility again and HTML is READABLE !

  • Vaviloff
    VaviloffApr 23, 2021

    Immense thank you, @brianboyko !

    So glad articles like these start to be written, providing simple and precise explanation of what is wrong with Tailwind.

    My personal a-ha moment came after inheriting a project with it. It was supposed to be a no-brainer, after all you don't have to learn someone else's home-made CSS framework with Tailwind (they say)!

    <!-- nope nope nope nope -->
    <nav class="absolute lg:relative lg:flex lg:text-sm bg-indigo-darker lg:bg-transparent pin-l pin-r py-4 px-6 lg:pt-10 lg:pl-12 lg:pr-6 -mt-1 lg:mt-0 overflow-y-auto lg:w-1/5 lg:border-r z-40 hidden">
        <li class="ml-2 mb-4 flex">                    
            <div class="hover:cursor-pointer text-white lg:text-indigo-darkest no-underline font-medium mobile-home-trigger"></div>
        </li>   
    </nav>
    
    Enter fullscreen mode Exit fullscreen mode

    Yeah, lg:pl-12 lg:pr-6 -mt-1 lg:mt-0, give me home-made CSS frameworks any time instead of this mess.

  • Antonio Maina
    Antonio MainaApr 23, 2021

    I find it easy to use tailwind for POCs. Especially since I use React, all I need to do is create my components and the rest of the team can use the component without thinking about the implementation details of that component unless they want to change it's design

  • Jesse Gavin
    Jesse GavinApr 23, 2021

    It literally provides no value, and tons of problems

    I started writing CSS for money in the year 2000. I am very familiar with CSS and all the different ways you can use it, LESS/SASS/BEM/SMACSS, etc.

    Tailwind provides a lot of value and solves tons of problems for me. I've been using it for about a year on a large Vue project. It's been really great.

    You can always supplement it with hand-written CSS. Sure it introduces some problems (like anything else), but the benefits far outweigh the cons.

  • Andreas Møller
    Andreas MøllerApr 23, 2021

    A good rule of thumb is that if people do something you think makes no sense. They probably know something you don't.

    In this case i think it might be several things.

  • Narendra Kumar Vadapalli
    Narendra Kumar VadapalliApr 23, 2021

    Wow, I was wondering if I should hop on the TailwindCSS bandwagon and came across this post at the right time . More than the article itself, enjoyed reading the back and forth between the developers in the comments section. This is such a healthy discussion I have seen in my career !

  • Lý Thanh Liêm
    Lý Thanh LiêmApr 24, 2021

    You really don't understand about Tailwind. Please know more about Tailwind and rewrite the article. About @apply keyword, customize theme. You are having a superficial view...

  • Dennis Zanetti
    Dennis ZanettiApr 24, 2021

    Well, I love Tailwind but I agree with some of the principles here, using 8000 classes inline is the thing I hate more, which is also why I hate bootstrap.

    However, with Component Driven Development, using BEM convention along with @apply for me is amazing, especially having Figma components based on Tailwind spacing, classes, etc.

    You can define your own project variables to use with Tailwind itself, so I can't see the problem.

  • imedacf
    imedacfApr 24, 2021

    Key point for not using tailwind is, that I have never ever had problem for what it is trying to do. I coded almost everything tailwind is doing just in an hour with my own classes and reuse it in projects, why would I mind to learn another thing, cause some people know too few things in styling/sass/less ? Use whatever you want, but don’t make such a big thing out of it.

  • Tanzim Ibthesam
    Tanzim IbthesamApr 24, 2021

    It adds complexity Because I dont have to use complex scss which is not easy to learn I can simply write all my classes in one file.
    As a backend developer it saves me tons of time since I dont have to main huge style sheets and I can do custom and responsive design without media queries in less time. Dont say that media queries doesnt take time.
    I can use @apply to style buttons and cards needed in specific parts.
    I dont need to use purge css with latest JIT compiler all myunused css gets removed automatically.
    Its not perfect nothing is but comparing css with a framework is like comparing React with vanilla JS not everyone has time to type 1000s of lines of css. or maintain ateam with people who writes css
    If it adds complexity rather than being judgemental and butthurt and doing personal attacks make a solution I believe. The official UI has support both both React and Vue.
    Deno documentation,Laravel,Nuxt and Netlify all have switched to Tailwind that is for a reason.
    I believe you are a great developer but your article is just butthurt and jealous or i believe you ahve past your prime and now is uttering some chatshit and nonsense to gain some cheap attention.

    If everyone is a fool and you are genius than people would be using your products and not Tailwind.

    • Kerry Boyko
      Kerry BoykoApr 25, 2021

      As a backend developer it saves me tons of time

      As a backend developer, what are you doing messing with the front-end? Honest question. I thought the general current paradigm was that the backend exports data - JSON/SOAP/XML - and the front-end consumes it via an AJAX call, rather than directly tying your backend to your presentation.

      • Tanzim Ibthesam
        Tanzim IbthesamApr 25, 2021

        I need to write CSS at times as I said Vanilla CSS sass everything is complicated not everyone has luxury of having designers. Why are you bringing backend jargons to comparison with a CSS framework you have lost your head.

        • robvirtuoso
          robvirtuosoMay 8, 2021

          Developers, especially backend ones, messing with UI design is one of the reasons why some websites look "that way". I'm sorry but Tailwind doesn't solve that.

  • Kyle C
    Kyle CApr 25, 2021

    Brian, why do you not want someone to use this library so badly?

    • Kerry Boyko
      Kerry BoykoApr 25, 2021

      Because, quite frankly, most of the projects professional engineers work on are not greenfields; we are bound by the decisions that were made by the previous owner.

      There's often not enough time to refactor, if a decision made in the past turns out to be the wrong one. Instead, you just add it to the technical debt.

      When I see a framework that's only going to cause problems down the road, I feel that I should warn people considering adopting it what those problems down the road would be, so that hopefully they choose something better, or at least go into it with full awareness of the things that they have to watch out for.

      • Alex Layne
        Alex LayneMay 10, 2021

        Have you ever actually inherited another person’s CSS before? I’d much rather inherent a Tailwind project. Maybe you enjoy working with CSS vomit, but I sure as hell don’t.

  • Nieuwe Pixels
    Nieuwe PixelsApr 25, 2021

    Great article, well written and your point is valid. Just because a lot of people are using it, doesn't make the case.

    In the end, everybody is free to use what they want, howevrt keep considering the up- and downside on the short and longterm.

  • Alexey Yurchenko
    Alexey YurchenkoApr 26, 2021

    Please don't use combinators in big projects...

  • Tanzim Ibthesam
    Tanzim IbthesamApr 26, 2021

    Lets wrap this discussion I am not sorry to this guy cause everything has its pros and cons but this guy could not provide rational argument in most cases.
    Why do we use framework because it eases our lives we could have just used Vanilla Javascript.
    Tailwind should be compared with Bulma Bootstrap and not with saas which i believe is a mess too and not a css framework and some like it. While Tailwind has some cons it is definitely solving problems for many and many are buying premium version I even dont own one.
    The way he bashed Tailwind we can also bash React Vue Angular and everything that exists.
    But if someone is using it let them use it rather than spreading negative judgements.
    This post was like begging people to not use Tailwind with mostly irrational arguments and most people who agreed I believe never made a full project with tailwind I understand they have their own preference .
    In return this post just gained negative publicity which at times is good for a brand.
    Bottomline nor people who need to use Tailwind are not gonna stop and neither the guy will provide an alternative solution.
    But if you ever bash a technology mention a few good sides and atleast have minimum respect to people using it.
    I am not replying anyone to this comment and I have deleted all my comments previously. Remember onething dont always see the world through your eyes a product might seem bad to you but its provides solution to others and people are making money. Everyone stay fine stay safe tc.

  • Owen Melbourne
    Owen MelbourneApr 26, 2021

    So many fallacies here - Just another case of a developer who has only half-assed the adoption process and doesn't understand design decisions that have been made.

  • 3200pro
    3200proApr 26, 2021

    I've been writing CSS since 2000. I love the way tailwind works. It's especially nice for modern website development. An agency owner I collaborate with just mentioned that he appreciates it because it unifies the frontend style of a website while allowing junior developers very strong documentation on the style guidelines.

    Everyone out there reading this that loves TailwindCSS checkout TailwindUI! I've been using the newly released React Components on my Gatsby websites and it's awesome. Super seamless, super optimized, and it's very fast to build out components.

    • amberpython
      amberpythonJun 19, 2023

      I actually start using Tailwind from TailwindUI with React, that's where I got the bad developer experience.
      It is ok to use tailwind UI as a whole component. but if I want to make changes to it, I have to read through hundreds of lines of html with really long classNames. the problem of tailwind is that it enable ppl not to think about components, which makes readability really bad.

      • 3200pro
        3200proJun 19, 2023

        I'm going to have to disagree. Unless you are trying to use it without purchasing them.

        The site has HTML showcasing the components on the frontend if you aren't logged in. If you purchase TailwindUI there are React versions of the components.

        *Example:
        *

        export default function Example() {
        return (
        <div>
        <label htmlFor="email" className="block text-sm font-medium leading-6 text-gray-900">
        Email
        </label>
        <div className="mt-2">
        <input
        type="email"
        name="email"
        id="email"
        className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
        placeholder="you@example.com"
        />
        </div>
        </div>
        )
        }

        • amberpython
          amberpythonJun 19, 2023

          I am talking about the full version of tailwind ui. take the pricing section for example, the three tiers component has poor readability. i cannot tell by a first glance the structure of the component. What I am trying to say is tailwind enable developers to write code like this. When I work in a team, it happens. The example is functional and performant, but it is not readable. If we are using styled component, for example, it will force the developer to carefully decide the components in that pages first, then we will see things like <Title/><PriceCard/><CardWrapper/><CardTitle/><PurchaseBtn/>, which will show the structure clearely.

  • Mike Holloway
    Mike HollowayApr 26, 2021

    I've recently used it in a project for the first time. I share some of your concerns.

    I was also using tailwindui, which is a set of patterns built on top of tailwindcss, so things got extra blurry for me.

    I felt like there was more html than required (tailwindui) and tailwindcss felt like "classitis" from back in the day. I also feel like I know CSS pretty well, but I was having to learn a new syntax for no real gain.

    The maintenance side also looks like a headache as you end up with really long classnames that scroll off the screen for days.

    I'm sure I've got plenty more to learn, but it's a rocky start.

  • Dmytro
    DmytroApr 27, 2021

    haters gonna hate

  • fr0tt
    fr0ttApr 27, 2021

    To be fair, when I first started to use Tailwind and obviously before that I was rather sceptical about using it because I thought aswell it would bring us back to earlier days, now frown upon, of inline styles. However nobody seems to care and I realized Tailwind is just one of many Utility-first CSS frameworks. You are correct in assuming that you could just write normal CSS instead of using Tailwind. That said I believe that frameworks are tools that help us not to repeat us. They are not necessarily some kind of magic, rather they just safe us time and writing all those handful classes by hand is possible but not needed.
    Maybe you should try to start implementing only the most basic things like for example colors, so you use text-orange-600, bg-orange-600, outline-orange-600, border-orange-600, ...
    You also mention using @apply it pointless. I sometimes find myself thinking about that aswell. Needles to say I do use it, because it mostly allows me to be consistent (especially with things like colors) and let's be honest, it's just faster to write :D

  • Ben Calder
    Ben CalderApr 28, 2021

    Look at all those comments!!!
    Looks like you opened a can of worms :D

    I've also been in the business for a while now and came to a similar conclusion about Tailwind. I do think the utility first approach has some merit; but I'd much rather just add a global stylesheet to a project where I define carefully tailored utility classes; rather than drop in something that does absolutely everything... and then waste time figuring out exactly which classes I need to use to meet my goal. The custom approach also has the added benefit that junior devs have a clearly defined selection of classes they're expected to use; rather than coming up with needlessly convoluted solutions using arbitrary Tailwind utilities.

    I think component-based frameworks have contributed to Tailwind's popularity. I've seen people obsessing over building all their styling into their components (so they are properly portable) when the likelihood of those components being used in other projects is literally nil. That can lead to a ton of unnecessary CSS duplication (because global CSS is apparently evil); and Tailwind looks like an effective solution to that problem; because it's just another dependency in your package.json...

    The real test for Tailwind will come when people have to implement re-designs 😅

  • Daniel Roth
    Daniel RothApr 29, 2021

    Not too many people want to post well-thought-out critiques. Done well, it is an important part of the conversation. Thanks for doing this.

  • Abdul-Samii Ajala
    Abdul-Samii AjalaMay 1, 2021

    You clearly just scratched tailwindcss from the surface

  • Mark Goho
    Mark GohoMay 6, 2021

    @brianboyko thank you so much for writing this article -- especially the part where you talk about why you wrote it. Additionally, while most folks won't read through all the comments, it shows an incredible level of dedication when an author takes time to read (not skim) comments and provide thoughtful responses.

    Apologies in advance for this very cynical and bleak perspective....

    While most of your article focused on technical reasons why Tailwind would not be a wise choice for most projects, I thought it might be helpful to at least call out why Tailwind is so popular in the first case: a lot of developers don't really know CSS, and they don't really care. Tailwind promises to make CSS more accessible for those developers. Unfortunately, I think a lot of your points above (which resonate with me, someone who knows CSS) just don't make sense to developers that have no strong desire to become proficient with CSS.

    Why would these folks care that @apply isn't in the CSS standard? They're told to use it by the Tailwind documentation and that's really all that matters.

    You make a great point about not being able to use combinators, but (really) who among these developers were ever going to use combinators anyway?

    Let's be honest: Tailwind is for developers that don't know and don't care to know CSS. Tailwind is for developers that want to pretend they use CSS.

    This is very similar to the extreme dependency on a grid system for layout when CSS Grid exists, is infinitely more powerful, and can be picked up in a weekend of study. Call it laziness, willful ignorance, or mediocrity, but Tailwind is popular and will probably remain so as long as developers don't want to do the work of learning CSS.

    • Jeff Sagal
      Jeff SagalMay 7, 2021

      Great take Mark. Had a good chuckle!

      Your perspective is neither cynical or bleak, but it is incredibly condescending and presumptuous, even more so than @brianboyko 's very condescending and presumptuous piece, so props on upping the bar! 🎊

    • Alex Layne
      Alex LayneMay 10, 2021

      I do know CSS and I also absolutely hate reading it. The reason I love Tailwind is that everyone writes CSS differently and with Tailwind you can’t do that. No more reading through an inscrutable CSS file, flipping back and forth from the HTML to figure out what the hell it’s actually doing. People don’t like Tailwind because they’re ignorant of CSS, they like it because in many cases it’s a better experience for both writing and reading it.

  • David Gil de Gómez
    David Gil de GómezMay 7, 2021

    What about @apply, I don't understand why you don't mention it, as it addresses at least some of the problems that you consider unsurmountable.

    • Kerry Boyko
      Kerry BoykoMay 7, 2021

      I do mention it.

      Second paragraph under " It solves a problem that doesn't exist. "

  • Dyedgreen
    DyedgreenMay 7, 2021

    While I agree with the overall sentiment; I’d like to add that tailwind is not as popular as it is without a good reason.

    I’ve used it myself before and I found that (at least when starting with a project), it makes it very easy to get something looking very modern and clean. I think the thing that makes people like it over eg inline styles is that yes, it’s “inline styles with extra steps”, but it’s also inline styles with prettier defaults.

    It can very quickly get you satisfying results.

  • Zsolt Molnár
    Zsolt MolnárMay 7, 2021

    Gosh... This conversation happened literally more than 10 years ago...
    Plus this article very conveniently ignores a lot of the features of tailwind.

    Also... Mission critical systems. I almost laughed. Have you seen a project with 10+ frontend developers each writing their own CSS in their own ways? How much complexity does that add? :D
    A CSS framework at least gives you 90% percent of the practices.

    But I agree with one thing. I also hate New Orleans Jazz....

    • Alex Layne
      Alex LayneMay 10, 2021

      He only knows how to use Bootstrap is my guess.

  • Victor Eke
    Victor EkeMay 7, 2021

    Something to think about. 🤔

  • Adityo Pratomo
    Adityo PratomoMay 7, 2021

    I'm feeling very represented by this article. I tried giving Tailwind a spin, create a simple website just for a practice. Few days in and I felt this is not for me. I get why people like it, but the fact that I have to constantly refer to the docs to remember the class name, felt counter productive, since I know the exact CSS property to do so. After completing it, I realize I have to fix several issues here and there, and guess what, the exact class name outlined in docs doesn't get recognized. I'm not sure what the problem is, but re-building Tailwind fixes the problem.

    But I get why people like it, writing a more concise inline CSS might suit some people. And I agree with the author. Not liking this tool doesn't mean that everyone should hate it. More choice, more power to the people :)

  • Giorgio Martini
    Giorgio MartiniMay 7, 2021

    I love functional css... havent used tailwind bt love tachions.

    • Alex Layne
      Alex LayneMay 10, 2021

      Tachyons was the first utility-first framework I used and I loved it. Tailwind’s like a version 2.0 of it. I don’t think anyone even maintains Tachyons anymore.

  • assertchris
    assertchrisMay 7, 2021

    Having read the article, I disagree with some of the statements and find others to be demonstrably inaccurate.

    Things I disagree with are mostly summed up in this part: "If you choose Tailwind for a mission critical application, you will end up making your job harder, your application more brittle, and your team, in the long-term, will suffer."

    I have not (anecdotally) found this to be the case. I maintain many applications that use vanilla CSS, many that use styled components + react, a few that use SCSS, and many that use Tailwind. I have not found apps that use Tailwind to be more brittle or cause me or anyone else in my teams to suffer.

    Fortunately, the onus isn't on me to prove a negative. I do not see any evidence to support your assertions, here. Only more anecdotal statements.

    Things that are demonstrably inaccurate:

    Thus, I find your article outdated, or disingenuous, or both. There are obviously pros and cons for each, but I find it's best to learn the substance of what you're trying to prove before you attempt to publicly shame a library/technology you don't appear to understand.

  • Buddy Reno
    Buddy RenoMay 7, 2021

    I keep going back and forth on loving Tailwind and not loving Tailwind. I need to go back and re-read the post more thoroughly (just skimmed it). Always good to read a well-thought-out counter point.

  • alistair smith
    alistair smithMay 7, 2021

    no words 🤣

  • lennyjuma
    lennyjumaMay 7, 2021

    You're just bitter other people are getting to understand css easier than you did and it actually works. Tailwind have taught me more css than writing actual vanilla css taught me.

  • assertchris
    assertchrisMay 7, 2021

    Having read the article, I disagree with some of the statements and find others to be factually inaccurate.

    Things I disagree with are mostly summed up in this part: "If you choose Tailwind for a mission critical application, you will end up making your job harder, your application more brittle, and your team, in the long-term, will suffer."

    I have not (anecdotally) found this to be the case. I maintain many applications that use vanilla CSS, many that use styled components + react, a few that use SCSS, and many that use Tailwind. I have not found apps that use Tailwind to be more brittle or cause me or anyone else in my teams to suffer. I do not see any evidence to support this statement.

    This that are factually inaccurate:

    • "You can't chain selectors together" You can. See: tailwindcss.com/docs/hover-focus-a...
    • "Now you have to go through each component and manually change..." No you don't. See: tailwindcss.com/docs/customizing-c...
    • "...explain what's wrong with Tailwind, but it really is a 1-to-1 mapping" No, it's not. You can't apply classes responsively in inline styles. You can't use
  • Manav Misra
    Manav MisraMay 7, 2021

    This is a bullshit title. Constructive criticism and OPINIONS is one thing, but the entire premise here is based on taking an extreme, disrespectful stance. I find it extremely beneficial to use Tailwind for a number of reasons as do many other devs.

    Mind you, I'm not 'defending myself,' as there's really nothing to defend. I am pointing out that a post with this type of title is barely worthy of a skim.

    Bullshit title.

    • Kerry Boyko
      Kerry BoykoMay 7, 2021

      I wouldn't call it bullshit.

      Clickbaity, maybe.

      • Reinier Kaper
        Reinier KaperMay 8, 2021

        Well "does nothing" is absolutely untrue, for starters, I don't think we need to debate that.

        "Adds complexity" heavily depends on your use-case. To give you an example: writing a component library is very, very efficient, without any increased complexity whatsoever.

  • Jacob Herrington (he/him)
    Jacob Herrington (he/him)May 7, 2021

    It's sort of ironic that the site this is posted on took inspiration from Tailwind in our own approach to CSS!

    I got a whiff of it and quickly learned the name is appropos: it was as welcome and useful as passed gas.

    It's entirely possible that was actually me. I produce a potent musk.

    It literally provides no value, and tons of problems.

    I respectfully disagree! Personally, Tailwind solves a lot of problems for me. For one thing: CSS is magic and I refuse to listen to anyone that thinks they can explain it to me because I might get hexed in the process. A tool like Tailwind keeps me safe from the dark arts (this is why I always burn sage when talking to @pp).

    More generally, I think critiquing Open Source tools for their issues is fair (especially if those critiques are attached to a PR!), but we also have to be mindful of the limits of our own perspective.

    As a CSS or front-end expert with a team of engineers to back you up, Tailwind might not be the best choice, but that doesn't describe all of us. When I build a landing page for a charity organization (I'm not billing, I can't handcraft all the CSS for this thing), I'm definitely using Tailwind or something quite similar. Tailwind is a great solution for those solo indie hackers out there; it improves productivity and abstracts a source of complexity that not everyone has the time or aptitude to dive into!

    Another way to phrase it: more or less these points would also apply to Rails or Laravel, but those frameworks solve a lot of problems.

    If so, why are we considering replacing CSS with something that does less, is more complex, creates bad quality codebases, and possibly ends up with massive vendor-lock in down the line?

    I'm not sure anyone wants to replace CSS with Tailwind! That sure is some all-or-nothing thinking (I learned about that in therapy, hell yeah)!

    You use the example of Assembly and C, but I think this is more like C and Ruby; I'm not a C developer, as much as I try to learn about it, but I can build some pretty cool stuff really quickly with Ruby. Of course, the stuff I build in Ruby is going to have some weaknesses for having used that abstraction, but if I didn't use Ruby I probably wouldn't ever get the code to compile anyway.

    However, I can go ask some friends who know C or Rust or something similar to extend my Ruby code when it really needs that performance boost!

    Maybe one day, I'll have to re-write my Ruby, but that's a problem for millionaire Jacob. He has more users and paying customers than his little Ruby app can handle.

    Tailwind doesn't stop you from cracking out that hellish CSS abomination whenever you want! When my Tailwind implementation makes something difficult I'll hire a warlock to summon whatever void-being we need to fix my layout.

    While we disagree, I'm glad we can have a discussion about it. Maybe you're right; if people find this article searching for more context around Tailwind, they will find a lot of opinions (and the strong stench that comes with a multitude of opinions).

    However, for now, I think the enlightened 21st-century philosopher-king Jason Mraz penned it more directly than I can every hope to: "You do you and I'll do me."

  • Nick DiMatteo
    Nick DiMatteoMay 7, 2021

    The answer to virtually all of your complaints is extracted components.

    Let's address your complaints one by one though:

    It's WET, not DRY.
    Not if you use extracted components.
    You have a wrapper class you like to use a million times? Great. Extract it! Then you only have to edit it once to update everywhere. Still DRY my dude.

    HTML should only concern itself with the structure of your page, not the styling of the page.
    These are inextricably linked though. Ever use a modifier class to change how your component appears? Where is that going? In your HTML.

    Know what modifier classes are eerily similar to? Utility classes.

    For example: need to stop page scrolling when a modal is open? Rather than writing a new class to do that, just use the overflow-hidden class already at your disposal.

    It's hard to read.
    I totally agree! ...So use extracted components.

    Now you can write your html with a simple class like card, and then go to town in your CSS with:

    @apply relative p-4 rounded-sm ...;
    
    Enter fullscreen mode Exit fullscreen mode

    You lose a lot of the features built into standard CSS
    Not true. Again, use extracted components.

    It solves a problem that doesn't exist
    At this point it should be obvious the problem it's solving, but just to clarify: it makes writing CSS easier and modifying your components in a logical way. Meaning, less time writing out individual css properties and values.

    You want to see an obvious problem it solves?

    I want a box to fill it's container, according to you I should just write plain CSS like so:

    .box {
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
    }
    
    Enter fullscreen mode Exit fullscreen mode

    5 lines of CSS I have to write or copy/paste from somewhere. And if I want to update the positioning to be 1rem in on each side? Now I have to update 4 lines individually.

    Not with extracted components:

    .box {
      @apply absolute inset-0;
    }
    
    Enter fullscreen mode Exit fullscreen mode

    If you want better than CSS, there are already solutions.
    All of the solutions you mentioned don't make writing CSS any easier. You mention CSS-in-JS solutions, but that goes against your argument that styling shouldn't be in your HTML and you mention BEM/SMACSS but that's just a writing convention.

    It literally provides no value, and tons of problems.
    There is massive value in efficiency. If you want to write code faster and keep your stylesheets lean, there is plenty of value in something like Tailwind.

    And I say this as someone who up until 6 months ago, refused to try out utility classes for similar hesitations. But instead of writing a big long post about why I think it's useless, I gave it a try and found a way to fit it into my workflow in a way that has allowed me to speed up my development time and still create accessible codebases for new developers (extracted components still live alongside regular CSS).

    BONUS: nowhere did you mention the treeshaking capabilities of tailwind. If you're managing large-scale sites with massive style guides and you care about bundlesize, that alone is a benefit of Tailwind that I'd find it hard for anyone to argue against.

    As an aside:
    Personally, I don't love when people use a platform like this, where lots of newcomers to our industry frequently look to for answers, voice an ~opinion~ that borders on condescension about something that they don't seem to fully understand.

    It's ok to have an opinion, or prefer different tools, but if you don't like something or don't understand the value, you don't need to pull a Tucker Carlson (???) response to it.

    Mic Drop

    • Ben Sinclair
      Ben SinclairMay 10, 2021

      Ever use a modifier class to change how your component appears? Where is that going? In your HTML.

      Yes, I've worked places where we do this. But I've also worked places where we use Bootstrap, and they're both bad ideas as far as I'm concerned. I don't think we should use modifier classes.

      • Nick DiMatteo
        Nick DiMatteoMay 18, 2021

        Who said anything about Bootstrap? I'm also very curious what you're doing instead of using modifier classes to style variants. Are you just writing inline styles? Duplicating other class styles to create a new class just to avoid this?

        I guess everything else I pointed out you don't feel like addressing? It's pretty clear to me that you aren't interested in wavering from your original "opinion" here.

        Best of luck navigating this industry with that mentality.

        • Ben Sinclair
          Ben SinclairMay 18, 2021

          Who said anything about Bootstrap?

          I did, me. What I'm saying is that I've worked places where we've used Bootstrap, which uses modifier classes and does basically all the things people criticise about Tailwind. Just because I've worked somewhere that does it a particular way, and where I go along with it because it's my job, doesn't mean I approve of something. So yes, I have and still do use modifier classes, and no I don't think they're the right approach.

          very curious what you're doing instead of using modifier classes to style variants

          Writing semantic HTML. Where there's an absolute client requirement to do something non-semantic, then adding classes beyond the semantic, but pushing back against it.

          I guess everything else I pointed out you don't feel like addressing?

          Everything else you pointed out was something I (mostly) agreed with.

  • Robbo
    RobboMay 7, 2021

    It's actually impressive how you can be so consistently wrong.

  • Guillaume Chau
    Guillaume ChauMay 7, 2021

    One of the biggest benefits of using tailwind is constraining styling to a set of pre-defined utility classes to follow a design system, and (almost) automatically have a consistent UI in terms of colors, spacing, etc.
    Not a single word about that in the blog post...

    • Guillaume Chau
      Guillaume ChauMay 7, 2021

      This is amazing for big/enterprise applications

    • Guillaume Chau
      Guillaume ChauMay 7, 2021

      Also did you give this post a read?

    • Alex Layne
      Alex LayneMay 10, 2021

      The author sounds like they’ve never had to work with a set of design standards and just use Bootstrap or some other gross and inflexible framework for everything. That’s cool if you want to make an incredibly boring looking site. I’ve done the “override styles in Bootstrap to make it less ugly” dance before, and it sucks compared to using Tailwind or any other utility-first framework.

  • robvirtuoso
    robvirtuosoMay 8, 2021

    Tailwind is the future of frontend???? What????

  • robvirtuoso
    robvirtuosoMay 8, 2021

    The problem with development in general these days is people like taking shortcuts. The mantra of "deliver fast" has clouded the (at least) equally important principle of "deliver quality". Tailwind and similar stuff are great for fast prototyping, but then again these prototypes tend to become "Minimum Viable Product" and therefore slips into production. And the nasty prototype code sticks in the product codebase through all production releases forever.

    Efficiency is one (good) thing, but laziness is a totally different thing.

    Tailwind just destroys a lot of good code design philosophies, and this article has pointed out many of them quite nicely. So I agree with this article and disagree with comments implying that this article is pure badmouthing.

  • Dr. Shawn Anderson
    Dr. Shawn AndersonMay 8, 2021

    This is a good explanation. There is a principle called "separation of concerns" that applies here.

    My only complaint is that you should never name a class the same as a key word.
    wrong:
    .flex{
    display:flex;
    }
    Is really bad form. You should do something like
    right:
    .flx{
    display:flex;
    }

  • sharath Kumar
    sharath KumarMay 8, 2021

    When it comes to Components, Tailwind makes sense.

  • LuisPa
    LuisPaMay 8, 2021

    you can save a lot of time just saying “I don’t like it” and that’s it.

    use what do you prefer, I’ll listen jazz while writing some tailwind classnames 😄

  • Jeff Caldwell
    Jeff CaldwellMay 8, 2021

    I tried Tailwind a few months ago and enjoyed how fast it was to prototype something at first. Once I started really getting into the project I found myself frustrated at a lot of the behavior you mention above. While I'm not exactly a CSS master I find it much, much easier to embrace the cascade and work with the strengths of CSS.

    Check out the C.U.B.E. methodology if you get a chance (it's not a framework!): cube.fyi/

  • Benoît Rouleau
    Benoît RouleauMay 8, 2021

    Hey, I fixed this article: dev.to/benface/tailwind-css-might-...

  • Andy Richardson
    Andy RichardsonMay 9, 2021

    Gotta agree with you here.

    css-without-using-css doesn't need to be a thing imho.

  • Aleksei Berezkin
    Aleksei BerezkinMay 9, 2021

    Thanks for explaining me why I don't need it. How I understood: with CSS you write 10 statements to style some component; with Tailwind you write approximately the same number of Tailwind classes. So I don't see a reason I should even bother trying 😉

  • Alex Layne
    Alex LayneMay 10, 2021

    This article is more worthless than a hot fart.

  • Angeiͥͥͥͥͥͥͥͥͥͥͥͥͥͥ
    AngeiͥͥͥͥͥͥͥͥͥͥͥͥͥͥMay 10, 2021

    I wasn't expecting a tweetstorm cause this post.

  • Lothar Grieb
    Lothar GriebMay 10, 2021

    My feeling is that the author of this article is more at home in the theoretical than in the practical world, otherwise you would never come up with such a post.
    There are many ways to reach the goal, and fortunately many good tools for daily programming and earning the daily bread.
    I find this criticism disrespectful only because it does not meet the personal taste of the author. Readability and design of code are as individual as daily life. So, each as he likes!

  • Aaron Nagucki
    Aaron NaguckiMay 10, 2021

    UPDATE: I ONLY use tailwind classes. I have zero @apply's in my code and I do not have any SASS/SCSS. I wrap most of my styles up in components.

    You're completely missing the point of Tailwind. @apply is the powerful paradigm shift NOT utilities. Sure, It's utility-first...NOT utiltiy only(that would suck) as in quickly prototype and then apply custom classes. Get instant media-queries and even dark modes. We built a completely custom design system for a large company completely powered by tailwind. so you just add the "button" class, get the designed button, but you can add utilities IF you're trying to see how a modified or alternate or one-off theme could look like. Then, after all is said and done, whatever classes you aren't using, get taken out of the file so that you don't have extra bloat.

  • Carvalho Tchipepe
    Carvalho TchipepeMay 11, 2021

    First of all congrats on pointing to Benoit Rouleau post. I am a tailwind fan, I read his and he is really angry.
    I do understand your frustration and see where you are coming from. Correct me if I am wrong but it seems like you are mad at Tailwind because somebody forced you to use it, despite the fact that there were better options. Aren't you Shooting the messenger instead focusing on the message? Tailwind is just a tool designed to perform a specific task and with every tool there is a technique and a use case . I used to hate it a lot and I would prefer writing css from scratch or use bootstrap, but I gave it a try and for rapid prototyping it is a great tool. I love customizing things in real-time, especially when I am doing demonstrations, and it has so many options. I really love it and Adam did a great job here. I am really sorry for you, you are missing a lot without Tailwind. My challenge to you would be helping to make it better.

  • Maciej Jendryczka
    Maciej JendryczkaMay 12, 2021

    Tailwind really scared me away for a long time when I first saw it. Although I never considered it as basically inline styles in a class attribute, long chains of classnames were off-puting.

    Until I really tried it in my Vue-based project, which has one specific need - ability to provide many options for initial theming of app instance. Not only colors, but buttons, inputs, layout to some extent etc.

    And as many people in comments said, tailwind config is the place when it really starts to shine in terms of customization and "the management center".

    On top of that component based frameworks like Vue really works with it nicely, at least for me. I'm all about separation of concerns, but not having to constantly move between template and style sections is convienient once you get used to it. I can focus on logic which is ideal if it doesn't rely on querySelectors anyway, components should be small if possible, so tailwind doesn't bite back.

    In my opinion there's no CSS framework in existence that would not fail without proper planning of using it. Styles needs as many planning and strictness as other parts of frontend to avoid inconsistencies.

    I really don't like React, kinda like Vue and really like Svelte. But those preferences came out from my personal experience with them, I can write how I don't like the shadow DOM and JSX to immediately receive response that they're not a dealbreakers and JSX is an attempt to avoid Vue/Svelte template magic - who wins? Someone who finished a project. But then competition was never about a technology being used.

    Bootstrap really got under my skin during it's fame, cause a lot of people wanted to use it on front websites...where from my perspective it was a tool for creating more technical things with established UX components and quick prototyping, not hacking it from Adobe Photoshop design into client's site with many whoopsie-doopsie layout ideas. Bootstrap + Adobe...very dark times for me. But it was popular, so it was required "in case of changes needed from other developer". Add code bloat to it, float clearfixes where inline-block, although also hacky, didn't throw content out of document flow just to put it back after and yeah...nope for me. But in my opinion it's a perfect example of harmful hype, maybe you had similar experience with TailwindCSS (everyone wanted to use it everywhere).

    Wrapping up, cause it's a long one - just because it didn't "click" for someone and there's a ton of fuss about it forming one more cult around it (especially then) - doesn't mean it's useless. It's just another way, especially when at first it's strengths can be overshadowed by questionable approach (here - coming back to tags highways). Sometimes the best thing to do is to try something new in a sandbox - away from hype noise, deadlines and already existing projects to rewrite. Cause work environment with a time span, sometimes stubborn teammates/clients and waterfall of new frameworks keep coming can put everything in a bad light.

  • Avichay Eyal
    Avichay EyalMay 13, 2021

    TailwindCSS, Much like any BEM structures on HTML, much like ANY CSS library depends on utility classes, is ABSOLUTELY ANTI-PATTERN and nothing good comes out of it in the long run.

    I totally agree.
    Wrote about it here eavichay.svbtle.com/never-bem-again

  • Luca Bertaiola
    Luca BertaiolaMay 15, 2021

    I agree with every letter in this post. Tailwind is inline styling, there's nothing good with it.

  • Andrei Rusu
    Andrei RusuMay 19, 2021

    It seems like you’re going at great lengths to say that you don’t like New Orleans Jazz, which is to say that you don’t like Jazz at all. I’m guessing you’re not into Free Jazz either. However, Jazz is pretty much everywhere in New Orleans especially on festive days like Mardi Gras.

    Also, Jazz is not really made to sell albums, that’s not its purpose, so I would refrain to suggest that. Jazz was initiated as a form of protest music, as an act of liberation, so learning to appreciate it wouldn’t be so bad I would imagine.

  • Yash Desai
    Yash DesaiMay 21, 2021

    I partially agree with you...
    but have a look at this...
    No, Utility Classes Aren't the Same As Inline Styles | frontstuff
    frontstuff.io/no-utility-classes-a...

  • David Quartey
    David QuarteyJun 13, 2021

    Tailwind CSS is only a tool which can be used anyway the wielder pleases. If you decide to write all the utility classes inline, so that you'd have to edit them one by one when there's a change, good luck.

    But as you noted, you can simply create a class and apply the various styles you need on that class using @apply. With this, you can combine selectors pretty much like plain CSS.
    It saves you from writing long CSS styles, pseudo classes, and media queries. Your HTML documents will look the same, and your CSS documents would be shorter.

    On top of that, adding dark mode support to your entire application is a breeze with Tailwind CSS.

    So I say the advantages of Tailwind CSS over Plain CSS would be:

    1. Less code
    2. Faster development
    3. Easier to implement responsiveness
    4. Dark mode is super easy to add

    That does not sound like using a revolver in place of a nail gun

  • Kevin
    KevinJun 20, 2021

    I've got to admit, everytime I look into Tailwind, I find myself asking what is the point of it. I don't see what benefits it has over just writing CSS. Personally, I think it's easier and quicker to just write CSS.

  • しん
    しんJun 25, 2021

    Now you have to go through each component and manually change "text-blue-500" to "text-red-500". And with 1000 edits comes 1000 oppertunities to introduce a bug. It is almost a textbook definition of why the DRY principle is in place.

    Alternatively, if you're using regular-old CSS, what you probably did is create a class called ".button".

    First, you can define primary color in tailwind config so all you have to do is change it to red in this case.

    Second, Tailwind is meant to be used with a component oriented system like React or Vue. You don't have to manually edit 1000 places for a button, instead you just need edit one button component.

  • simplyphp-kelly
    simplyphp-kellyJun 30, 2021

    Personally, I thought the same thing when I saw Bootstrap add utility classes, and everyone and their mother suddenly using them. "Hey, look at this! I can do

    This is a test! and I don't have to touch any CSS!" Isn't that just inline styles with extra steps? But at least Bootstrap still gives you components and you don't HAVE to use those utility classes. Tailwind is much, much worse; from what I can see, it's almost entirely classes like this, and it seems like a major step back for CSS design. If you're going to litter your class attribute with a million and a half styling classes, why not just cut out the middleman and use style="" directly?
  • Sandor | tutorialhell.dev
    Sandor | tutorialhell.devJul 19, 2021

    As a senior dev you know that there is no best tool. All points you mentioned are valid, by they depend on the context.

    With custom CSS you often find yourself doing exactly what tailwind is doing. Then you struggle with naming things and end up with lots of unused CSS that you know there is in your CSS but you just do not dare to remove it.

    Right at the start you know bow complex your designs are and you can quickly asses the overhead you may have with not being able to use the cascading nature of CSS.

    There are tons of use-cases where Tailwind will save you a lot of time and money not to mention a built in support of themes and even dark/light modes.

    There are ways to mitigate some of the disadvantages of Tailwind and despite it somewhat defeating the purpose of utility-first approach, it does not mean that Tailwind is a bad choice.

    I use it where the benefits outweigh the disadvantages. And I do it because I know how unmaintainable custom CSS can become especially when many people work on.

    it's your opinion and I agree with many points. But I strongly disagree that TailwindCSS does nothing. It's a trade off...

  • Vitaliy Yanchuk
    Vitaliy YanchukSep 22, 2021

    Reading style horizontally is the only one enough reason not to use TailwindCSS, also all the cryptic names of classes. I don't want to learn cryptic version of css properties I already know.

  • Mahdi Naderian
    Mahdi NaderianOct 6, 2021

    After taking a look at your article I realized one thing:
    ...You truly don't know how to use Tailwind CSS for real.

  • Darryl Noakes
    Darryl NoakesOct 28, 2021

    I would say that CSS-in-JS is a screw/screwdriver, and Tailwind and cousins are the nail guns.

    The screw requires a screwdriver to use, which is a rather different tool to a hammer, but it achieves a very similar outcome.

    If you use it correctly, the nail gun allows you to quickly and neatly shoot in some nails, but it isn't always flexible enough for what you need to do. In that case, don't discard it: use the nail gun to quickly do all the main stuff, and use the hammer when you need to.

    If you don't use a nail gun correctly, you can hurt people. But you can also hurt people with a hammer or screw driver. And nail gun wounds are usually clean. Hammer wounds are not.

    P.S. Check out WindiCSS.

  • Gerd
    GerdNov 23, 2021

    This article is just full of ignorance. If you would learn to actually use the system, ie... take a deep dive and truly learn it, you would find that many of the things you point out are absolute rubbish. For instance look-up the @apply directive. @apply lets you apply all the classes to one class. That's just one example. I could point out so many other things in your article that are so wrong.

  • anplusdre
    anplusdreDec 3, 2021

    Agree, long ass html classes will wreck you. Good luck with querrySelectorAll ByClassName or worst good luck using it in angular. There will be alot of !important, return Null, and conflict everywhere

  • MilMike
    MilMikeJan 13, 2022

    "and starts hammering in nails with the butt end of a loaded revolver (Tailwind)."

    well said! thats how I experience it too. I tried to use tailwind in few projects, but as the project got more complex, re/styling it was a huge pain in the ass..

    It might be good for smaller projects and when you simply start and need to design components quickly, but even then, you need to learn the new syntax, I could almost do the same crap in style="..."

  • Evans Edosa
    Evans EdosaJan 14, 2022

    I’ll agree it’s difficult to read

  • LeoDaoTao
    LeoDaoTaoFeb 9, 2022

    Interesting opinions here... I've been writing HTML and CSS by hand since 1999 (full use of CSS a few years later since support in 1999 was still iffy). I agree with the author, Brian Boyko. I have researched Tailwind extensivelly. I just don't see the benefit. It feels like we are going back in time when FrontPage generated all our styling inline. I hated it then, I still don't like it now. However, I think maybe a lot of developers do not really grasp CSS. It's another technology to learn. In that case Tailwind may be a good option.

  • theonewhosighs
    theonewhosighsMar 8, 2022

    One of the fundamental false assumptions in programming is that you're going to happen upon things that are reusable while writing your code. And thus you write everything for potential re-usability, despite the fact that it also makes your code more ugly.

    CSS outside of Tailwind has this exact problem to a T. The idea that you're going to create this easily modifiable theme for your website where all you have to do is change a few definitions on a handful of classes and everything is good, is laughable. If you have enough reason to restyle small things, you're likely going to have enough reason to redo the entire layout of the site. And then those classes you built up in CSS are suddenly going to be useless. And there's a good 50/50 chance that a lot of your CSS that just sits there in your file are dead definitions that don't actually get used.

    Tailwind embraces the reality that components and the like are highly specialized & rarely reused outside of library code.

    As for losing out on CSS features, there's no reason why you can't use both. If you have something you genuinely know is going to be used tons of times, it's completely acceptable to just define that thing. But in the large amount of cases where things aren't going to be used tons of times, tailwind saves you the back and forth between CSS files and what's on the screen.

    There's another side tangent here where, honestly. The article suffers from a lack of acknowledging the existence of modern component/template libraries. Lets say you genuinely had a button with the same style across the entire website. There's 0 reason why that button couldn't be a component with its styles set, that gets reused everywhere. There's no reason why you shouldn't be able to create a "PrimaryButton" component in: put your templating infrastructure here.

    Then changing the styles on that button across the entire website is incredibly trivial. If it's something you're going to reuse across the website 40 times anyway, may as well make it easier to reference too.

    And as for HTML being about the document and not styling. That was false the day HTML was made. In fact, the way we structure documents often comes down to our styling desires. Why is something inside multiple div tags with different classes, even though it's just a text blurb & an image? Because we needed all of that to make our pretty slider.

    There's no way to separate HTML from the styling system. Styling inherently requires DOM manipulation for anything more complex than simply displaying text on the screen.

  • saroopjack
    saroopjackMar 15, 2022

    Sharing my opinion as a beginner. At first i hated using tailwind, the more i learned about tailwind the more i liked it. But the only downside i personally faced with tailwind is not being able to use the combinators. i guess the developers will find a way to include that in newer versions

  • jonrose-dev
    jonrose-devApr 23, 2022

    You captured my feelings on tailwind perfectly. This will be my reference going forward the next time I’m dragged into this debate.

  • relliv
    rellivJun 28, 2022

    I know most front-end developers disagree with me :).

    I think Tailwind CSS is the best way to build web apps quickly for backend and full-stack developers. Because I am one of them. When I started building web apps there was only bootstrap. Yes, bootstrap solves many problems but still, I couldn't warm up to CSS. Because CSS is too primitive (yes I know the CSS is an engineering product) I couldn't use it. Then I loved CSS when I use SASS but still, again there are missing some things. I need more speed and simplicity. Finally, Tailwind solved all problems for me.

    These days we are not developing simple websites. If we choose the long way we can lose a lot of time. If you can use the right tools you can save time. And you can move next step.

    This article has some right arguments and I think some titles are outdated now (2022).

  • The Becaye
    The BecayeJul 6, 2022

    Tailwind allows me to have consistent CSS on my whole app.
    Let's not even talk about how easy it is to make your website responsive with tailwind instead of writing annoying media queries.
    How could you not love it?

  • evbo
    evboOct 19, 2022

    @brian boyko I'd maybe revise your statement about similarities to inline styles. It's well known that tailwind is only responsible for generating CSS. How that CSS ends up in the HTML is ultimately up to the build system - not tailwind.

    And this is an important fact too, because CSPs have been under growing scrutiny to block all inlines. When you look at it from that perspective, Tailwind is doing all of us a world of good having one more tool in our toolbox to avoid unsafe inlines.

    Second thing to consider: tailwind encourages devs to drop frontend libraries in favor of rolling their own UI. So, in that respect, it is actually like more of a gateway technology into learning more about CSS - not avoiding learning it.

  • Xevion
    XevionOct 30, 2022

    To me, this article is just another one of those opinions. Tailwind is not the ideal solution for everyone. If you're looking to rapidly prototype a website and produce results quickly, Tailwind is an excellent choice.

    But if you're looking to maintain a monolithic codebase with well defined layouts and schemes that may need small individual tweaks and updates that occur globally, then yes, Tailwind doesn't really help the solution.

    If you don't really know what your codebase is going to look like, you're still playing around with your layouts, and you're making tons of little tweaks on micro scale, Tailwind can make these changes super fast. Not everything deserves to be a full fledged CSS class, you know.

    But yes, when you have your codebase figured out and things aren't changing all over the place, you can begin to translate Tailwind into a more structured and elegant CSS-first solution (or better yet, SCSS). Plus, you get all the time in the world to waste naming classes once you're not in a rush developing truly useful code.

  • Avabucks
    AvabucksNov 18, 2022

    Consider this avabucks.it/
    Very good article, appreciate it.

  • iway1
    iway1Nov 26, 2022

    IMO inline styles are better for modern web dev. if you want to keep it dry you should do so by reusing components instead of some other CSS shenanigans, as reusing components is a lot easier to think about and generally ends up being cleaner. If you're reusing styles separately components your codebase is becoming much more complex for no good reason.

    Anything that's not inline is necessarily a lot more effort to create something that's harder to understand fundamentally

  • Adam
    AdamApr 9, 2023

    At last... Someone, who thinks the same... We can talk about dynamic class/style... oh! sorry, **tailwindcss **doesn't have that eather...

  • paul shorey
    paul shoreyApr 14, 2023

    Love the image "This is just inline styles with extra steps". Perfect! Haha!

    Remember CoffeeScript? Yea. When everybody has to refactor their website/app originally built with Tailwind, they'll realize.

  • paul shorey
    paul shoreyApr 14, 2023

    All this fuss about Tailwind is probably in anticipation of React/NextJS moving towards server-side components, which don't support CSS-in-JS which needs to manage a stylesheet on the client. So a library of classNames works around that.

    Try SCSS Modules. Works in NextJS 13 server-side components! Tiny bundle size.

    Most frameworks support at least the basic CSS Modules. Standard. Composable. Modular. Time-tested. Easy to work with. Efficient, small bundle!

  • hellowwworld
    hellowwworldSep 1, 2023

    Few cents:

    1. Nobody stops you to define colors as primary, primary-light, primary-lightest
    2. Nobody stops you from having config with common use cases either
    3. Nobody stops you from mixing bem/sass/etc with tailwind, it will still compile.
    4. Readability problem is also imaginary. You can easily group classes for readability and add any custom logic with clsx.

    In other words you wrote a sketchy review about based on shallow experience.

    P.S. css in js is inferior

  • Andreas Herd
    Andreas HerdJan 29, 2024

    I agree with everything said here, it's liked because of it's simplicity. Inline styles are quick and dirty and a lot of newbies and devs in general like quick and dirty, which explains why tailwind is liked beyond reason.

Add comment