DEV Community

Gravy59
Gravy59

Posted on

 

Tailwind CSS: A critique

TailwindCSS is a prominent CSS framework that has grown in popularity in recent years. It has a wide range of pre-built utility classes that make styling HTML easy. My opinion on Tailwind is mixed, as it seems to provide the same amount of benefits and drawbacks.

Design Constraints

TailwindCSS's design constraints are one of its greatest advantages. It includes a set of precise design principles that maintain a uniform look and feel across all website parts.

Extensibility & Configuration

Tailwind's config file allows you to create any number of CSS properties, and their new JIT arbitrary values are essentially inline css - which in some cases is exactly the issue with Tailwind.

Preflight

Tailwind Preflight is amazing - built on top of modern-normalize, Preflight resets the default inconsistent styles across modern browsers. In addition to modern-normalize, Preflight:

  • Allows devs to apply a border just by setting a border width
  • Ensures horizontal rules are visible by default
  • Removes gaps between table borders by default
  • Resets all font sizes, buttons, and other styles on elements to allow the user to rebuild them without any default styles getting in the way
  • And much more

I would actually use preflight in a project without Tailwind.

Tailwind is great, but there are a lot of drawbacks.

Lack of Abstraction

Tailwind CSS doesn't abstract away the underlying CSS. Instead, it provides a set of pre-designed utility classes that simply modify the styles of HTML elements. This can sometimes result in massive, bloated class names that are not that better than inline styles.

Repetition

Tailwind isn't as friendly to reusable components compared to something like BEM. Applying styles to a component becomes tedious, and even Tailwind acknowledges this.

  <div class="mt-3 flex -space-x-2 overflow-hidden">
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80" alt=""/>
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
    <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1517365830460-955ce3ccd263?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
  </div>
Enter fullscreen mode Exit fullscreen mode

Tailwind docs

you’ll inevitably find yourself repeating common utility combinations to recreate the same design in many different places.

Their solutions are flimsy at best. They recommend that you
A) Use a framework, which not all developers want to do, or
B) extract styles with their @apply directive, which do anything about the problem Tailwind was intended to solve.

The first solution works fine from a workflow standpoint, but at compile time you're still left with bloated class names (even if Tailwind purges unused css) that in some cases can balloon file sizes.

A Tailwind component with a massive amount of class names
Aleksandr Hovhannisyan - Why I Don't Like Tailwind CSS

Conclusion

Tailwind is great for rapid prototyping. It's extensibility makes it trivial to stay conformed to a design system. Preflight is one of the best ideas ever, and more people need to use preflight or modern-normalize to make their lives easier. Unfortunately, Tailwind also suffers from large, sometimes unmaintainable class names that can be extremely repetitive and balloon your HTML file sizes.

Thanks for reading! REMEMBER TO USE MODERN-NORMALIZE IN ALL PROJECTS FROM NOW ON

Top comments (23)

Collapse
 
ben profile image
Ben Halpern

Good post.

I agree with the general thoughts here, also feel like Lack of Abstraction is probably the most surprising delight here. The shallowness of the abstraction makes it such a good layer for so much work I've done with it.

I'd say my biggest agreement here is the repetition part here. Tailwind gives you a lot of rope to hang yourself with, and I think the right way to avoid problematic repetition is whatever you come up with yourself, Tailwind isn't helping much!

Collapse
 
bcostaaa01 profile image
Bruno • Edited

I’d say that Tailwind CSS is definitely not my favourite CSS tool, but I’d point two advantages of the tool anyways:

  • speed of development, since it’s a library of pre-defined classes and you can create designs quickly.

  • consistency, since it reduces the need of custom CSS styling.

I’d say, the configuration is the worst part of it.

Still, CSS can be so powerful and so much more fun to work with, as long as you invest the right amount of time to it. There are far cooler tools to use like Styled Components, for example :)

Collapse
 
yoquiale profile image
Alex

Disagree, Styled components feels like it's counter-intuitive and it's an unnecessary bloat.

Collapse
 
bcostaaa01 profile image
Bruno

Could you please elaborate on that? I mean, it’s not the easiest tool to learn either, but it does offer more reusability when you compare it to building CSS modules in a React project, but that’s just my opinion. Would be keen on hearing about others’ perspectives as well!

Thread Thread
 
gravy59 profile image
Gravy59

Styled components are 12.42kB min+gzip on base, so a bit large. I do like how it is similar to tailwind in that your styles aren't decoupled from html, and there is twin.macro for tailwind. I also think you should check out Stylify from @machy8, which is a cool hybrid of the two.

Thread Thread
 
bcostaaa01 profile image
Bruno

I understand your point and reasoning!

Thank you for sharing your thoughts and for the recommendations!🙂

Collapse
 
abutahermuhammad profile image
AbuTaherMuhammad

you're right.

I was about to mention configuration. It's still something that bothers me on every project...

Collapse
 
acode123 profile image
acode123

I personally believe that traditional CSS is a lot better, it's not that hard, and it's more reliable.

Collapse
 
machy8 profile image
Vladimír Macháček

Hi @gravy59 ,

I have posted Best Practices for Utility-First CSS right now and saw your article.

I understand your points, but in the same time I disagree with you.

Even though I am the author of Stylify CSS, which is an alternative to Tailwind, I will defend the Utility-First CSS "base" here.

In my humble opinion, I think, that a lot of "bad things" about Utility-First CSS (Tailwind, Tachynos, others), simply come from "laziness" and the "simplicity of utilities usage" and a lot of them can be avoided by simply thinking things ahead, splitting the code and using the tool features correctly.

You can style any website that is using Tailwind with pure CSS, but let's face it, writing CSS isn't easy. It is for a small blog. But when the project starts to grow, you can get even 200+ css files. It's hard to maintain, clean, and compose together to get the correct bundle for the page, selector names often makes no sense and not even bem will help you, there are lot of duplicates, etc...

Every tool have its cons but utilities solve a lot of issues, not just fast prototyping and small size.

But I understand that not everyone likes to see a lot of classes in one attribute.

Collapse
 
etienneburdet profile image
Etienne Burdet

I agree that their solutions to repetition are flimsy at best… but they also highlight the fact it doesn't really solve the problem it claims to —as you point out.

If you need Svelte or Vue (or any form of templating) to factor repetitive patterns, this days it means you also have css scoping anyways. Meaning you can just name your stuff carelessly… if you name it at all. I mean, I hardly use classes in Svelte, I just go straight for nodes 🤷 And then, you just jump the problem one level up: you don't name your css classes, but you have to name your components.

And then again, you build fast, but how maintainable is it? Want to change all spacing in cards. You look for .card-spacing? Of course not, you hunting for mx-4… ho, unless that one that was an mx-2 with a px-2 and that one that looks like a card but is panel… "We should put names on things, no?"

Collapse
 
naubit profile image
Al - Naubit

Great article, you got my follow, keep writing!

Collapse
 
pengeszikra profile image
Peter Vivo • Edited

When I make simple HTML without any CSS, just enough to import tailwind cdnjs and that is enough for joy all advantage, for example: tailwind sticky test - I make one css for <p>. Much fare easiest solution, and I never need to think about class names.

your example in react:


export const ImageList = ({imageList = []}) => (
  <div class="mt-3 flex -space-x-2 overflow-hidden">
    {imageList.map(({src, alt}) => 
       <img src={src} alt={alt} class="inline-block h-12 w-12 rounded-full ring-2 ring-white" />
    )}
  </div>
);

// on img tailwind class is uninportant parameter so I put the end of line.

export const App = () => {
  const imageList = [
    {src: "https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" , alt: "-- something meaning full --"},
    // other images, but mainly this list coming from some database
  ];
  return <ImageList imageList={imageList} />;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
theredfish profile image
theredfish • Edited

My brain works best with backend development but I should say that Tailwind CSS is the only frawmework allowing me to build beautiful UIs. It's very logic in its approach and coupled to a framework like NextJS it feels like perfect to me.

Everything is a component, each component has inline CSS. For common things like titles, images, etc... I use the @apply directive. Works like a charm, the feedback loop is really fast and unless you have important size constraints I can't see how Tailwind CSS is an issue.

But as I said, I'm more a backend developer than a frontend developer so not an expert at all!

Collapse
 
brense profile image
Rense Bakker • Edited

Not to mention their solution for repetition: use a framework... A lot of UI component frameworks make using tailwind obsolete.

Another major drawback of tailwind is that it does everything at compile time, making it impossible to access your configuration at runtime, something that css-in-js solutions do support. For example in emotion you can access the entire theme object at runtime. Because tailwind classes are made during compilation you also cant use any dynamic values. For example, if you have to make a white label app... You'd have to use css variables and manipulate those with your own custom JavaScript which is extremely obscure and sucks for maintenance.

Collapse
 
gravy59 profile image
Gravy59

You actually can access the config at runtime - just importt your tailwind config as an es module.

Collapse
 
gravy59 profile image
Gravy59

There's also twin.macro

Collapse
 
danwalsh profile image
Dan Walsh

Interesting post, @gravy59, but there are a few points that I feel need clarification or expansion to give everyone "the whole picture".

I originally started writing a comment, but it got a little long, so I moved it to a post instead:

Collapse
 
gravy59 profile image
Gravy59

Thank you! I appreciate your insight - I also love tailwind but I try to see both sides of an argument. I didn't realize you could gzip html!

Collapse
 
danwalsh profile image
Dan Walsh

I'm glad you enjoyed my post reply! I'm always a little worried it might be taken poorly. So glad we can have productive conversations on dev.to! 😊

Yep, gzip is awesome, but not something (as a frontend developer) you typically have to worry about, as your sever-level configuration should have gzip compression configured and enabled.

Collapse
 
fanreza profile image
Muhamad Jamil

Im always use tailwind for Vue project, usually I use the framework too like daisyUI, and I agree about the bloated css class names that's why I use @apply

Collapse
 
yawaramin profile image
Yawar Amin

I mean sure, if a developer doesn't want to adopt the approach that Tailwind recommends, then they will have an unsatisfactory experience. Tailwind is not for everybody, not everyone wants to adapt to its recommendations. That's OK, but painting that as a downside of Tailwind is like saying that a downside of tea is that you like coffee better. Doesn't really make sense.

Collapse
 
kkm000 profile image
Cy "kkm" K'Nelson

Every time I hear the word “framework,” my hand involuntary reaches for the Reset button. When it is qualified by the adjective “opinionated,” it's the 7lb hammer and not the Reset button, for it's ideology sensu primo pushed upon you.

Historically, most of the successful frameworks has never been called so, neither by their authors nor users. In fact, of successful AND self-termed frameworks, I can probably name only .NET. I've been in the trade for 35 years.

In terms of project planning, If you have to use a framework self-termed or widely accepted to be a “framework,” multiply your time estimate by 10. This is my standard.

Oh, and I never wrote a Web site in my life, or heard about this this Tailspin framework, or how it's called. Even less had any reasons to use it. My statement is general.

Collapse
 
acode123 profile image
acode123

Good points.

12 Rarely Used Javascript APIs You Need

Practical examples of some unique Javascript APIs that beautifully demonstrate a practical use-case.