aleksandrhovhannisyan.com icon indicating copy to clipboard operation
aleksandrhovhannisyan.com copied to clipboard

Why I Don't Like Tailwind CSS

Open AleksandrHovhannisyan opened this issue 3 years ago • 56 comments

Note: Please keep comments civil. Abusive comments will be removed.

AleksandrHovhannisyan avatar May 11 '21 11:05 AleksandrHovhannisyan

Hey, Somehow stumbled on your blog. I was also sceptical as you are.

  1. Tailwind Makes Your Code Difficult to Read No it doesn't. It's the opposite. As soon as you get the hang of it it makes you faster.

  2. Tailwind Is Vendor Lock-in No it's not. The project is OS and you could fork it. Already some people are working on slightly different versions.

  3. Tailwind Is Bloated No it's not. It just compiles the classes that you actually use for prod.

  4. Tailwind Is an Unnecessary Abstraction If you think so. I like abstractions. I like to do more with less.

  5. Semantics Is Important. Tailwind Forgoes It. The tailwind way makes much more sense imho, as I get much more input with less letters.

  6. Tailwind and Dev Tools Don’t Play Nicely I am doing pretty fine with just an inspector. You see the classes applied by tailwind and what they're doing. What more do yo want?

  7. Tailwind Is Still Missing Some Key Features More features are coming - don't worry.

Did you try it for let's say for more then two weeks? Because it definitely has a learning curve. You also don't learn VIM in an afternoon...

Have fun!

Manubi avatar May 26 '21 21:05 Manubi

I agree with @Manubi. Tailwindcss is very awesome in my experience! I think we should try it for a while in order to evaluate something. I tried it and loved it. I agree with all from https://tailwindcss.com/. cc @adamwathan

anton-karlovskiy avatar May 29 '21 02:05 anton-karlovskiy

I hate @tailwindcss but not for the same reasons. I hate tailwind because it's low level. I'm not a designer 🤷🏾‍♂️, bootstrap is enough for my taste.

SamAsEnd avatar Jun 21 '21 09:06 SamAsEnd

Thanks for this post (including updates based on new learnings you have found since writing it). I have always been hesitant about Tailwind, and now I feel like I have a better vocabulary to explain some of my thoughts.

I always found that the "quick prototyping" thing sounds awesome, but I'm not sure it would be worth the time investment to learn, and certainly it would slow my team down to introduce a whole new paradigm. We have absolutely stolen some small ideas from it though, and now have a small utilities.less file which contains one-offs like .margin-left-sm or .flex.

Overall I do think that it's slightly over-hyped, but I love that the people who use it are loving it and are finding it enjoyable. 👍 I also think the team behind it has done an awesome job, regardless of who is using it/what their use-case is. I probably won't be migrating entirely to utility-based CSS, but I think having the option to sprinkle it in for very common styles makes sense and is a good idea.

himynameisdave avatar Jul 13 '21 17:07 himynameisdave

Really great article; I was looking for a position against tailwind to tamper my excitement for it, and this did a great job pointing out it's difficulties/drawbacks. I still very much value Tailwindcss' quick prototyping abilities, it's elimination of much boilerplate when you simply want to add a few styles to an element, and how a utility-frst framework is natural to how we think. If you look at large code bases, you will find them moving toward utility-first classnames. All that said, thorough article.

bryantbrock avatar Aug 02 '21 23:08 bryantbrock

I have been designing and doing CSS for over 3 decades and utility first is the future IMHO.

Most frameworks have utility styles but only until you fully embrace them are they really useful and powerful.

The offer still stands. Try it for a while and see if you don't start to love CSS again. I did.

ShaggyDude avatar Aug 11 '21 19:08 ShaggyDude

I find myself having a slight preference for semantic css, after working with both Tailwind and Bootstrap on recent projects. I like keeping styles scoped (using preprocessors or BEM) and keeping as few styles polluting the global scope as possible. It feels like a good general programming principle to adhere to, and I think it applies to CSS as well.

adamalfredsson avatar Aug 13 '21 15:08 adamalfredsson

Semantic CSS is a myth but, if you enjoy coming up with names helpful for designer / developers you can extract component classes with @apply.

Thanks for the discussion and I don't work for tailwind! lol

ShaggyDude avatar Aug 20 '21 19:08 ShaggyDude

I agree with most od those arguments but I have one stronger. In pure CSS a senior or lead developer can set some rules, define grids and create initial variables. Then all the less experienced devs can just reuse them. This way we have a consistent design across the whole app.

I found out that with Tailwind everyone tends to just throw m-4 wherever they want, some other time it will be m-3 and then someone else will use other numbers and the whole beautifully designed things breaks. And let's say we need to update something later. You literary need to go through all the HTML and change the spacing. Hell.

Lack of cascade is also a super problem in my opinion. My titles are separated to a component, but then I want them to have different spacing around them depending on the context they are used. Is there a subtitle after? Is it placed after an image? Is it in the main article or in the header? I don't want to thing about it each time and wonder 'was it m-5 when there is a subtitle or m-4'? And even if I remember this someone other in the team will just throw m-2 cause he needs a spacing there.

With cascade you set it once and then your title class can be used even by you back-end guys as it will always look good and consistent, no matter whey they put it. No one needs to think about it. It's there, it will work.

In a project where things change and gets updated I am highly irritated working with Tailwind and wanting to say 'fuck this, I quit'.

z-x avatar Sep 01 '21 18:09 z-x

Agree with all the points. It just makes everything harder to maintain, harder to read, and more importantly it does not solve the issue it claims to solve: duplication. There is just plenty of duplication but inside class field of each element.

fuksito avatar Sep 22 '21 18:09 fuksito

Agree with this. I actually found out the hard way by making a project with tailwind. It's not that bad for iterating quickly, but the html quickly becomes unreadable, and without cascading logic you get a lot of repetition.

I have found the best way to migrate away from its use - to do so in stages . Use @apply with existing tailwind classes -alongside other css rules- as part of a normal css cascading rule set and so slowly wean off canonical tailwind use in html classes, over time.

december1981 avatar Sep 30 '21 16:09 december1981

I'ved used normal CSS at deep level, plain Bootstrap CSS and Styled Components and Material UI styles in React.

I haven't used Tailwind CSS before, heard about it, and read a full article on it's code. But I don't like it. It reminds me too much of plain Bootstrap CSS class notations, which I wasn't a big fan. Too much stuffs to relearn just for doing the same thing.

I'm an algorithm guy, I prefer everything to be setup programmatically, and avoid plenty of static class names filling my HTML scripts. I prefer Logic over Memory approaches. CSS attributes list are enough for me.

KeitelDOG avatar Oct 06 '21 20:10 KeitelDOG

FYI: https://twitter.com/dan_abramov/status/1452324924421550080 cc @gaearon

anton-karlovskiy avatar Oct 24 '21 18:10 anton-karlovskiy

I think open-props can be a good alternative - https://youtu.be/BuRAvafvGTA

sharu725 avatar Dec 19 '21 12:12 sharu725

Ex-tailwind-hater here.

I learned CSS from MDN and that classical paradigm to styling was the only way I knew about. So I hated tailwind for the first time I saw it. I won't count reasons, many articles cover them.

I still believe tailwind is bad in the context of classical styling paradigm... BUT, if you embrace it as a different paradigm for styling your webpage, it really is great!

Also, for those who don't like completely linear class list of it, I agree with you.

So during development I style my html as such:

<nav class="
    flex 
    items-start 
    bg-[#F8F9FA] lg:bg-transparent
    shadow-md lg:shadow-none  
    p-6 
    sm:max-w-screen-xl 
    w-full 
    left-0 right-0 
    my-0 mx-auto
    sticky top-0 lg:absolute
...
  • Those classes who are more or less separate are on newlines.
  • If a class has responsive sister classes, I put them on the same line.
  • If some classes work on similar things (like left-0 right-0) I put them on same line as well.

This way I can read and debug the code easier.

That was my two cents. (If you don't agree, please don't hit me 😉)

ghost avatar Feb 14 '22 14:02 ghost

@alpersunter Fwiw, I've been going back and forth on this a bit myself. In fact, I recently updated my site to rely more heavily on utility classes, especially for stuff like font sizing and layouts. I think a balance between using a CSS methodology and relying on utility classes can work well. I'm still not a fan of going all in on utility classes, especially for media queries and very atomic properties, but it doesn't hurt to use utilities where they make sense.

AleksandrHovhannisyan avatar Feb 14 '22 16:02 AleksandrHovhannisyan

I think I will get murdered for this for potential clashes with html tags that may be added to the html spec in the future and other??? reasons:

I use svelte/kit where css is scoped to the component. I rarely use classes or ids, preferring a semantic approach with which I guess are called "HTMLUnknowElements", e.g:

<style>
    list {
        display: flex;
        flex-direction: column;
    }
<style>
<list>
    ...
</list>

Much more readable than a div soup with tailwind classes!

myleftshoe avatar May 21 '22 12:05 myleftshoe

okay, i'm already converted! Using tailwind with DaisyUI.

The ability to cut and paste html without worrying about the css too is nice.

One senior dev on youtube (i think) pointed out that he hates tailwind because his team don't consistently use the same variants eg, one will use m-3 and another m-4. Understandably frustrating, but a lot less troublesome than inline css (highest granularity and multiple units)

Considered open props as well - looks awesome - may use as an in-betweener.

myleftshoe avatar May 23 '22 07:05 myleftshoe

When using tailwind I did end up finding that my code became a lot harder to follow. For what it's worth you can do this and make use of svelte's style tag again!:

<a href="/">Home</a>

<style>
  a {
    @apply underline text-blue-600 hover:text-blue-800;
  }
</style>

Thanks to Kaan Divringi for this idea - Making sense of Tailwind in Svelte

myleftshoe avatar May 28 '22 05:05 myleftshoe

Master you CSS. Make your own framework. Don't waste your time learning how to work with the latest toy offered by the market. End

crosales1979 avatar May 31 '22 08:05 crosales1979

Honestly, this article is a big joke and extremely misleading due to one major misunderstanding by the author in how TailwindCSS works:

Quote from the article:

Finally, remember that point I brought up earlier about how Tailwind CSS promotes ugly HTML markup? Supporters of the framework usually respond by reminding you that you're probably working with a component-based framework like React anyway, and so you're unlikely to be looking at a giant sea of markup in a single file. Fair point.

TailwindCSS doesn't promote "ugly HTML" at all. TailwindCSS is a utility framework, thus it mostly depends on how you use it and it gives you the ability to use it in a clean or a comletely fucked up way. The latter relating to what the author of this article interpreted as the only way of using TW. What the author didn't understand ist that you should not clutter the class attribute of an HTML tag with 3000 Tailwind utility classes but rather actually only set your custom class name in the HTML tag and then put all Tailwind utility classes in the @apply ...; CSS at-directive in your custom CSS class block.

Imagine not considering this in the whole article!

I've been using TailwindCSS for some years now and styling has never been easier!

Cheers

qbasic16 avatar Jun 03 '22 14:06 qbasic16

Sorry but you were wrong about being wrong on number 4 (Tailwind is bloated). Of course it is bloated. Who cares about the css file, it get cached anyway but your bundle file does not get cached and that doubles easily in size with all repetitive classes.

And about missing features, I'd rather see min, max and clamp and support for css custom properties.

But the most problematic in a component based framework is that you can't reuse components without adding JS logic to all components in the component tree. This creates code opacity and adds to unnecessary complexity. With regular css you only need to switch a class in the parent and use the cascade to get a different styling of the same component tree/page/what ever. (imagine being asked to do an A/B test) On top of that you probably have to pass props for the change which creates strong couplings between components, violating the SOLID principles and therefor inducing rigidity in your project. Which hampers your refactoring ability and code flexibility.

If you already added it to your repository and now want to exit from it you'll quickly notice that it will be a painful divorce. Tailwind creator could have done something to improve this by lowering the specificity of their normalizer (preflight) but they have not which I think is disingenuous. Same goes for the marketing of Tailwind which should be narrowed down to prototypes and temporary sites.

nicolashervySKF avatar Jun 13 '22 06:06 nicolashervySKF

Great article and I share your arguments completely.

If you find yourself at the point where you're @apply'ing dozens of utility classes in a semantically named class, with vanilla CSS pseudo-selectors mixed in, ask yourself where it all went wrong. Readability and compile times are suffering, stack complexity and maintenance went up (PurgeCSS), and the added requirements for new front-end hires mean candidates will be in shorter supply. All to save a few keystrokes.

I feel the initial novelty of utility classes and Tailwind's stickman demonstration of them got a lot of devs on the TW hype train, but when that train ultimately derails in complex projects, the sunk cost fallacy kicks in. It's an expensive decision to recover from.

oscaralexander avatar Jun 20 '22 20:06 oscaralexander

Some of this is cherry picking: That's 71 class names just to style a checkbox. - yeah, very cherry picking. And stuff like this: it requires you to pan your eyes horizontally rather than vertically. - so why don't you categorize the classes where you break them? No one is forcing you to keep them all in one long file - look for solutions not problems.

If you've done enough TW, this gets easy, and also, this is self explanatory really:

items-*: align or justify?
content-*: align or justify?
justify-*: content or items?
align-*: content or items?

I'm not sure the person that wrote this article https://www.aleksandrhovhannisyan.com/blog/why-i-dont-like-tailwind-css/ - has used TailwindCSS for more than a project or two or three, except some test run projects.

Semantics Is Important. Tailwind Forgoes - well no and no. You get used to it, and you are free to add semantics. Why add semantics in Scss variables like primary-color when you can just add that in the config with tailwind?

Remember Scss? You would write your config files in a variable table... well, tailwindcss has just that. Plus, everyone knows the convention so its easy and cheaper to onboard new devs as well, instead of having 20000 different guidelines for different conventions and whatever.

I can't read any more of that article, and I just skimmed it....

AurelianSpodarec avatar Jun 28 '22 04:06 AurelianSpodarec

I just barely tipped my toes into TailwindCSS with Svelte, PostCSS and vite and I must say, I ditched it already.

Why?

Because even once I have extended the grid columns template, I couldn't get it to dynamically set based on the amount of array elements. That's a deal breaker for me. Even after adding it to the safelist and all, it did not work, but it worked if I wrote the string grid-cols-3days literally as a value into the class attribute. Yet if I did class="{gridColumnsTemplate}" and verified, that the browser dev tools showed the class at the element, the corresponding CSS effect did not appear.

The workaround would've been to get the element onMount and add the element to the classList - sorry, but why?! If I wrote the classes on my own, they'd be available within that component and I would've been able to simply use that variable I mentioned earlier to apply the class to the element.

Long story short: I'll just write CSS, perhaps SASS, if I'll need it.

divStar avatar Aug 22 '22 01:08 divStar

Hey, Somehow stumbled on your blog. I was also sceptical as you are.

  1. Tailwind Makes Your Code Difficult to Read No it doesn't. It's the opposite. As soon as you get the hang of it it makes you faster.
  2. Tailwind Is Vendor Lock-in No it's not. The project is OS and you could fork it. Already some people are working on slightly different versions.
  3. Tailwind Is Bloated No it's not. It just compiles the classes that you actually use for prod.
  4. Tailwind Is an Unnecessary Abstraction If you think so. I like abstractions. I like to do more with less.
  5. Semantics Is Important. Tailwind Forgoes It. The tailwind way makes much more sense imho, as I get much more input with less letters.
  6. Tailwind and Dev Tools Don’t Play Nicely I am doing pretty fine with just an inspector. You see the classes applied by tailwind and what they're doing. What more do yo want?
  7. Tailwind Is Still Missing Some Key Features More features are coming - don't worry.

Did you try it for let's say for more then two weeks? Because it definitely has a learning curve. You also don't learn VIM in an afternoon...

Have fun!

Tailwind Makes Your Code Difficult to Read No it doesn’t. It’s the opposite. As soon as you get the hang of it it makes you faster.

How can it be easier to read many CSS selectors horizontally, than read CSS property/values vertically? It seems to me that Tailwind CSS is just another way of writing an inline style, which is an absolute NO NO, because inline styles are not modular. HTML should describe what an element does and CSS should describe what an HTML element looks like.

Tailwind pollutes the semantic nature of HTML.

charlesr1971 avatar Aug 25 '22 08:08 charlesr1971

Some of this is cherry picking: That's 71 class names just to style a checkbox. - yeah, very cherry picking.

This isn’t cherry picking. This is a great example of how utterly obtuse, Tailwind CSS, is. Having looked through a few code bases that use Tailwind, these kinds of long strings are not unusual. Yes, you can format the class attribute content, but that then makes the surrounding HTML difficult to read. But the biggest problem is that the HTML is no longer semantic. I mean, you might as well use an inline style? This is essentially what Tailwind is doing:

Tailwind:

class=“tw-w-[20px]”

Inline style:

style=“width:20px;”

charlesr1971 avatar Aug 25 '22 08:08 charlesr1971

How can it be easier to read many CSS selectors horizontally, than read CSS property/values vertically?

What you still don't understand is that you ONLY write Tailwind Classes inside HTML for prototyping or non-reusable HTML. The clean way to use Tailwind utility classes for reusable styles, is to wrap them inside your own CSS classes, which you would write anyway, even without Tailwind, using the @apply at-rule.

qbasic16 avatar Aug 25 '22 08:08 qbasic16

I mean, you might as well use an inline style? This is essentially what Tailwind is doing:

Tailwind:

class=“tw-w-[20px]”

Inline style:

style=“width:20px;”

Read this: "No, Utility Classes Aren't the Same As Inline Styles".

qbasic16 avatar Aug 25 '22 08:08 qbasic16

@qbasic16 - what? https://twitter.com/adamwathan/status/1559250403547652097

z-x avatar Aug 25 '22 09:08 z-x