DEV Community

loading...

Why Tailwind Isn't for Me

Jared White
Founder and lead developer at Whitefusion, a boutique web studio located in Portland, Oregon. On the core team of Bridgetown, a static site generator. Proud Rubyist!
Updated on ・9 min read

March 2021 Update: the experimental new JIT (Just-In-Time) compiler for Tailwind has the potential to alleviate some of the concerns outlined here and also provides some intriguing new benefits. I haven't tried it out yet, but once I do I'll formulate additional thoughts and link to them from here. -JW

I've gotten into more than one heated argument on the interwebs lately over Tailwind CSS. I'm not proud of this. I don't like being at odds with anybody. I think the folks building Tailwind are talented and nice people. But at a pure technical level, I simply don't like Tailwind. Whoever it was built for, it was not built for me.

And in one sense, that's fine. There are tons of web technologies out there which I'll never use. Doesn't mean they're bad. There are plenty of groovy tech stacks to go around.

The problem I keep running into however is this increasing popular sentiment that Tailwind is the future (man). It's the way things should be done. In other words, it's opinionated and it inspires a cadre of evangelists. Again, on a certain level, that's fine. Rails is very opinionated, for example, and I love using Rails.

But Tailwind definitely throws down a gauntlet. I'll quote directly from creator Adam Wathan highlighted right on the Tailwind website:

“Best practices” don’t actually work.

I’ve written a few thousand words on why traditional “semantic class names” are the reason CSS is hard to maintain, but the truth is you’re never going to believe me until you actually try it. If you can suppress the urge to retch long enough to give it a chance, I really think you'll wonder how you ever worked with CSS any other way.

Challenge accepted.

I've tried it. And I've used it. A lot. A project one of my largest clients has me developing is built on top of React and Tailwind. So whatever you may come at me with, you can't accuse me of not giving Tailwind the good ol' college try.

Still not my thing. At all. In fact I have some real concerns about Tailwind, and what I find supremely frustrating is whenever I raise these concerns, I get immediate pushback from die-hard Tailwind fans who accuse me (in so many words) of just being a fucking idiot. As a programmer who has worked full-time in the web industry since the late 90s, that just doesn't sit right with me.

So since Twitter and Hacker News comments are apparently poor mediums for technical conversations of this magnitude, I will now attempt to outline the very real reasons why Tailwind is not for me.

Reason 1: Tailwind promotes ugly-ass HTML.

This first reason is an aesthetic concern, yet it's intimately related to real technical challenges which I'll outline shortly. But at the very least, I hate the way utility-css-only HTML looks. Hate, hate, hate it. Adam even acknowledges this head on when he begs us to "suppress the urge to retch long enough to give it a chance…". This is a tacit admission that writing markup this way initially seems ugly and weird—but somehow we'll eventually just "get over it" because the benefits are so great.

After a year of writing Tailwind, I haven't gotten over it. Sorry folks! You'll never get me to appreciate this:

<div class="min-w-0 flex-auto space-y-0.5">
  <p class="text-lime-600 dark:text-lime-400 text-sm sm:text-base lg:text-sm xl:text-base font-semibold uppercase">
    <abbr title="Episode">Ep.</abbr> 128
  </p>
  <h2 class="text-black dark:text-white text-base sm:text-xl lg:text-base xl:text-xl font-semibold truncate">
    Scaling CSS at Heroku with Utility Classes
  </h2>
  <p class="text-gray-500 dark:text-gray-400 text-base sm:text-lg lg:text-base xl:text-lg font-medium">
    Full Stack Radio
  </p>
</div>
Enter fullscreen mode Exit fullscreen mode

Now I already hear many of you screaming at your computer screens to tell me "dude, just use @apply if you want to keep your HTML clean! Problem solved!" Well, that is a potential solution, and in fact that's what we've done on the aforementioned project. Much of our HTML is oriented around component-scoped class names (fairly close to BEM in concept) and thus we use @apply extensively. But that brings me to my next concern.

Reason 2: @apply is fundamentally incompatible and non-standard (and largely unnecessary).

This is where a lot of Tailwind fans get tripped up and keep on arguing with me over and over again, so I'll try to explain this as clearly and obviously as possible.

  1. @apply mt-3 in a CSS file only works if you use Tailwind. It requires the presence of Tailwind in your build process. If you remove Tailwind from your build process, that statement doesn't work and your CSS is broken.
  2. While it's true you can take the generated output CSS of a site and use that without Tailwind, it's typically a bundled compilation of dozens if not hundreds of small CSS files scattered around a codebase (if you write CSS-per-component files like we do). It's not something you can count on for source code.
  3. Therefore, it's simply the truth that CSS files built for Tailwind are non-standard (aka proprietary) and fundamentally incompatible with all other CSS frameworks and tooling. Once you go Tailwind, you can never leave. (da da dum 😱)
  4. And as an added bonus, writing all your CSS files with @apply everywhere basically means you're not learning and authoring CSS. You're authoring Tailwind. No matter how many times you write @apply flex, that's not the same as writing display: flex.

Now I realize most of us aren't in the habit of trying to swap out CSS frameworks on projects on a regular basis. But believe me, I have done this! I'm on a client project right now where we're migrating from Foundation to Bulma. While it's true that it requires updating a bunch of HTML and some of the stylesheets in use, rest assured any custom bits of styling we wrote before will work again without hassle, because when you write plain ol' CSS (or even Sass), it just works no matter what.

And while @apply seems cool on the face of it, it ends up becoming an enormous crutch. For example, I like the way Tailwind makes writing styles using CSS Grid techniques pretty straightforward. Unfortunately, after having done so, I still don't really understand Grid syntax itself. I remain ignorant of the open CSS standard.

As for why @apply in the grand scheme of things is largely unnecessary, that brings me to my third point.

Reason 3: Tailwind's focus on design systems and tokens could mostly be replaced by CSS Custom Properties (aka variables)—which IS a standard.

People initially like Tailwind because it comes out-of-the-box with a nice design system and lots of tokens you can tweak (colors, font sizes, spacing, etc.). It's easy to get good-looking results quickly.

The problem is that all these tokens are defined…in JavaScript. A CSS framework. Using JavaScript for its design tokens. In 2021.

I hate to break it to you, but all modern browsers support this thing called CSS Custom Properties. You can define design tokens once at the :root level as variables, and utilize them everywhere. You can even modify them in real-time while the site is loaded, or overload them in particular parts of the DOM tree. And they work great with web components. More on that in a moment.

So for example, in Tailwind you can write class="mb-8" and you get a margin-bottom: 2rem style applied. But guess what you could do instead? Define :root { --spacing-8: 2rem } in your stylesheet, and then write margin-bottom: var(--spacing-8) anywhere you want. As in literally anywhere: a stylesheet, or a JS component, or even a style= attribute directly in HTML!

While the story gets a little murkier once you start looking at how to accommodate responsive breakpoints and so forth, nevertheless the principle here is that Tailwind uses a non-standard JavaScript-based build process for its design system at a time when you can build design systems using syntax that's native to all modern browsers.

Speaking of what's native in modern web browsers…

Reason 4: Tailwind forgets that web components exist.

This is perhaps the biggest knock against Tailwind. It seemingly was conceived and promoted in a world where web components don't exist. Tailwind CSS is completely unusable within the Shadow DOM. Some enterprising developers have come up with solutions where select bits of Tailwind styling can get injected into components through a build process, but it's definitely a hack.

Meanwhile, there are ways to build web component-based design systems today where global theming and component styling via the Shadow DOM (and exposed Parts) all work together. Again, you can do all this based on technology that's built-in and native to all modern browsers. And before you shrug your shoulders and go back to your React or your Vue, bear in mind that web components are not only an integral part of the HTML/CSS/JS spec today but are increasingly at the heart of further advancements to browser technology (for example how advanced customization of form controls might work in the future).

Tailwind in this respect is no more helpful to you than Bootstrap or Foundation or any other CSS framework written years/decades ago. (Even my beloved Bulma! 😢)

Reason 5: Finally, Tailwind encourages div/span-tag soup.

I almost included this in the previous point, but it really bears its own conversation. I have become convinced by now that using <div> and <span> tags everywhere in your markup is an anti-pattern. We live in a world where custom elements (aka <whatever-you-can-dream-of>) are fully supported and enabled by modern browsers. There's virtually no reason you're forced to write <div class="card"></div> when you can write <ui-card></ui-card>. And in fact it's quite possible to use custom attributes along with elements to write extremely expressive markup that—compared to ye markup of ol'—looks quite futuristic!

Take the Shoelace web component library for example. Here's a button:

<sl-button type="default" size="small">
  <sl-icon slot="prefix" name="gear"></sl-icon>
  Settings
</sl-button>
Enter fullscreen mode Exit fullscreen mode

And here's a modal:

<sl-dialog label="Dialog" style="--width: 50vw;">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  <sl-button slot="footer" type="primary">Close</sl-button>
</sl-dialog>
Enter fullscreen mode Exit fullscreen mode

Note that this isn't JSX. This isn't XML. This isn't some kind of fancy-pants template language you have to convert to ordinary HTML.

This is HTML. This is what modern markup can look like.

Compare that to an example from Tailwind's home page:

<button class="hover:bg-light-blue-200 hover:text-light-blue-800 group flex items-center rounded-md bg-light-blue-100 text-light-blue-600 text-sm font-medium px-4 py-2">
  New
</button>
Enter fullscreen mode Exit fullscreen mode

Ewwwww. 🤢

There is a future world of HTML/CSS/JS (and in large part it's here already) where you can write bespoke Grid/Flexbox layouts quickly and easily with vanilla CSS, set up design tokens with CSS variables, utilize a well-architected web component library like Shoelace (or even mix 'n' match two or three), and end up with a website/app that looks amazing and works quite well—all without needing any of the many megabytes of Tailwind utility classes that you then need to purge to get your performance back down to manageable levels.

In other words, Tailwind's main selling point (besides rapid prototyping via utility classes) is its attractive design system—yet the way it implements that design system really kind of sucks! (Incompatible with web components by default, only minimally leverages CSS variables, doesn't encourage custom elements/attributes with relevant scoped styling…)

Which begs the question: how does Tailwind enable us to "build modern websites" exactly? On a pure technical level, I honestly don't see it as being much of an improvement over Bootstrap. And Bootstrap at least provides an open-source component library for free. If you use Tailwind, they ask you to pay for it.

Conclusion: If you like Tailwind, use it! But don't try to convince me it's the future.

Listen, we can go back and forth on the relative merits or problems with any technology. There are definitely some benefits to choosing Tailwind, most notably how you can go from blank page to fancy-pants design quickly by simply hammering out a bunch of div tags with utility classes.

But after over a year of experience with Tailwind and weighing the pros and cons against other approaches to HTML, styling, and component-based web development in general, I'm thoroughly convinced that Tailwind does not represent the direction I wish to see the web head in as a whole. And apologies to all the Tailwind fans out there, but you just don't have a compelling argument that will convince me otherwise.

And that's why Tailwind isn't for me. YMMV. 🙃

Discussion (198)

Collapse
jfbrennan profile image
Jordan Brennan • Edited

That was a great post dude. I experimented with Tailwind and share some of your same opinions, but you might be dismissing it a little too much. A balance of components and utility classes is what I’ve found to work well, especially for larger orgs that share a common design system.

I start with custom HTML tags and scale up to Custom Elements when JavaScript is needed. I implement a complete, but minimum set of styles for the component and leave room for customization with utility classes. My favorite example is an alert box:

<m-alert type="success">I’m a green box</m-alert>

<m-alert type="warn">I’m an orange box</m-alert>
Enter fullscreen mode Exit fullscreen mode

That component only requires a little CSS to style its tag (the m- prefix is for my library) and attribute, e.g. display block, some padding, border radius, and colored background per type attribute. I add an icon according to the type with :before and the result is a CSS-only component with a much more meaningful API that uses the same standard HTML constructs as native elements.

A component’s default style should be perfectly acceptable on its own, but should leave itself open to customization and that’s where a big collection of utility classes comes in handy. So for example, maybe bigger text and more padding is needed for a specific alert instance, just add some classes (but nothing to the extent that Tailwind requires):

<m-alert type="success" class="txt-lg pad-all-lg">I’m the same green box with bigger text and more padding</m-alert>
Enter fullscreen mode Exit fullscreen mode

I like this because it’s familiar and meaningful markup with no magic, no hacks, no dependencies, no boring div and span, and minimal to no classes. This alert component is usable everywhere and is compatible with any framework because it’s just CSS.

And like I mentioned earlier, one day when the alert grows up and needs JavaScript to support some new feature, like auto-dismiss after a given number of seconds, it can evolve into a Custom Element with no breaking changes or shifting paradigms:

<m-alert type="success" autodismiss="4">The same markup, but now I’m a JavaScript-enabled Custom Element</m-alert>
Enter fullscreen mode Exit fullscreen mode

I’ve a built a couple design systems following this pattern and the result has been good. I think it’s the balance that really makes the difference. Something like Tailwind is just as extreme as something like Material-UI and neither in my opinion offer the benefits of the custom tag and attribute pattern.

Collapse
jaredcwhite profile image
Jared White Author

I love this. Great examples! I also like how you described a kind of progressive development methodology there. That's very much how I like to think these days as well.

Collapse
oncode profile image
Manuel Sommerhalder

This is definitely the way to go. I had to take over legacy projects (just css and vanilla js) and each of them had growing utility classes mostly to make life easier by not having to write a variant class for every little change. But every project had different classes, different names. They felt incomplete, insufficient variables, hard to remember and not easy to switch between projects. This is where tailwind shines by providing consistency through all projects and being able to use your design tokens (margins/paddings etc.) with css classes. Then you put over custom elements for reusability and to bake in basic js and accessibility. And then vue/svelte/react for handling state, app structure etc.

Collapse
pepalinha profile image
pepa-linha

I don't think it's a good solution, even it's often used. If you add styles like txt-lg, pad-all-lg then you can get a lot component variations. You will lose track of which component variants are used in your code.

Collapse
jfbrennan profile image
Jordan Brennan

But are “a lot of component variations” the result of this method or do they actually originate with the designer? The designer. So, it’s a question of how to implement the designs in a clean and maintainable way.

Thread Thread
pepalinha profile image
pepa-linha

It is that point. How can you be sure it's from a designer? If you are a designer and you create a component that has two variants - success and failure. Then you can write code like this

...
...

So, everything with custom utility class (text-large, padding-large, border-radius-small, ...) is bad from me because that variant with custom class was not designed and developer invents :-) Then the consistency is broken. But it's just my point of view as a designer and developer in one.

Collapse
rizary profile image
Andika Demas Riyandi

Do you have any repo that you can share? It seems I need to follow this style.

Collapse
jfbrennan profile image
Jordan Brennan • Edited

I use M- ("em dash"). It's open source, so feel free to use it, fork it, contribute, whatever:
m-docs.org

Collapse
layzee profile image
Lars Gyrup Brink Nielsen • Edited

You had me at

<button class="hover:bg-light-blue-200 hover:text-light-blue-800 group flex items-center rounded-md bg-light-blue-100 text-light-blue-600 text-sm font-medium px-4 py-2">
  New
</button>
Enter fullscreen mode Exit fullscreen mode

Good luck redesigning that button across a site or application.

Collapse
karimmaassen profile image
Karim Maassen

And that's why Bootstrap killed the industry. This convoluted way of putting styling in HTML where it has absolutely no business is driving me insane.

Collapse
ritikpatni profile image
Ritik Patni

I already experienced the pain, and it's not worth it

Collapse
oncode profile image
Manuel Sommerhalder

the idea is that you put it into a vue component or css class with @apply for reusability

Collapse
layzee profile image
Lars Gyrup Brink Nielsen

Thanks for your reply. What would that look like?

Thread Thread
oncode profile image
Manuel Sommerhalder • Edited

your component:

<template>
  <button
     class="button"
     :class="{
      'rounded-md': rounded,
      'bg-light-blue-100 text-light-blue-600 hover:bg-light-blue-200 hover:text-light-blue-800': blue
    }"
  >
    <slot />
  </button>
</template>

<style type="scss">
// use apply seperately or all in one line
.button {
  @apply flex items-center text-sm font-medium;
  @apply px-4 py-2;
}
</style>

<script>
export default {
  props: ['rounded', 'blue']
}
</script>
Enter fullscreen mode Exit fullscreen mode

in your app:

<BaseButton rounded blue>Button</BaseButton>
Enter fullscreen mode Exit fullscreen mode
Thread Thread
layzee profile image
Lars Gyrup Brink Nielsen

Thanks for sharing. This looks cleaner, but I'm still wondering why this would be considered more beneficial than CSS Custom Properties except maybe for Internet Explorer support.

Thread Thread
oncode profile image
Manuel Sommerhalder • Edited

You can also use custom properties with Tailwind. Imagine you get a design (system) and have to implement it. You get some colors, margins, paddings, font definitions along with the design. You edit the tailwind configuration file:

module.exports = {
  theme: {
    colors: {
      primary: 'var(--color-primary, #000000)',
      seconday: 'var(--color-secondary, #333333)',
    },
    text: {
      hecto: 'var(--text-hecto, 14px)',
      octa: 'var(--text-octa, 16px)'
    }
    // margins, paddings
  },
}
Enter fullscreen mode Exit fullscreen mode

Now you will a get all (soon to be) needed (responsive) utility classes to build your components with, which are also themeable with css custom properties: text-primary bg-primary sm:bg-secondary border-primary hover:bg-primary....

It gives us a unified language where frontenders don't have to think about naming classes anymore and use a consistent language across different projects. You and others working on that project can easier implement the design, because ideally you now the class names by just looking at the design/figma. With vscode autocompletion and tailwind config viewer, it makes developing a joy. :)

With just custom properties, the class names are not set, different names across projects. It's not ensured, that the custom props are used by every developer when adapting new features, no responsive prototyping, and and and.

Collapse
toffee_coin profile image
Elijah Lucian

if you're going to go out of your way to make a component and a custom css class name, just write css!

Collapse
markpieszak profile image
Mark Pieszak

My thoughts exactly 💯

Collapse
pavelloz profile image
Paweł Kowalski

I have one word describing revolutionary approach in software development that might help: extraction.

Collapse
wakematta profile image
Mohamed Ziata

It seems that nobody knows that in tailwind you can make css classes that share same style.
Read: tailwindcss.com/docs/extracting-co...

Collapse
hyperpress profile image
John Teague

You had me at WebComponents and ShadowDOM. The creator of @apply revealed that it was poorly conceived. And I agree. I don't have a dog in the CSS FW fight because I don't use them. There are obviously lot's of folks that are fond of Tailwind, and that's fine. But I want to stay as close to the platform as possible. More generally, I think humans mostly overcomplicate CSS, and I frown on apps that need to build half the internet to function. My 10 cents.

Collapse
shaileshcodes profile image
Shailesh Vasandani

I've written my own CSS for most of my projects and tried Tailwind for a small one a while back. It never really sat well with me and I was never able to really figure out why, but I think your article really puts it into words very well. The fact that we have technologies like WebComponents that are already super well supported just makes the div soup that is Tailwind feel so unnecessary. Of course, no hate to those that use Tailwind; after all the beauty of the HTML and CSS standard lies in its very flexibility.

Collapse
swyx profile image
swyx • Edited

nice post Jared :) I won't try to convince you but for those who want an opposite viewpoint this is my take on Why Tailwind. I'll link to your post from mine, for balance.

Collapse
jaredcwhite profile image
Jared White Author

Thanks for sharing, these are well-considered points.

Collapse
silvenon profile image
Matija Marohnić • Edited

FYI, you can totally configure Tailwind to use Custom Properties as color values instead of hex:

module.exports = {
  theme: {
    colors: {
      purple: 'var(--color-purple)',
      yellow: 'var(--color-yellow)',
    },
  },
}
Enter fullscreen mode Exit fullscreen mode
Collapse
s5b profile image
Stuart Begg

I know this is just an example, but goes to a pattern of implementation.

What happens cognitively, and also semantically when I later make this change?

:root {
  --color-purple: goldenrod;
}
Enter fullscreen mode Exit fullscreen mode

Now, everything that was originally selected to be 'purple' (via the theme and css) is a completely different colour, everywhere it's used.

This kind of styling has no meaning to me. And often has unexpected consequences when you make changes, like the one shown here, above.

I much prefer using role-based elements and components with semantic qualifiers for the styling: using words like 'warning', or 'header', or 'quote', or …

For me, mixing the presentation with the content (markup) just makes managing and refactoring the implementation that much more difficult and error prone.

Collapse
jaredcwhite profile image
Jared White Author

That is legit good to know. 👍

Collapse
otijhuis profile image
Okke Tijhuis

It's what I do as well. My tailwindcss config uses CSS Custom Properties for basically everything; colors, spacing and so on. That way I don't have to use @apply, I just use the custom properties instead. I also get consistency between tailwind and my own CSS. Change the property and everything gets updated. It also saves me from manually writing all the utility classes that I want. Like you I don't like tons of classes in the HTML but having to write your own classes whenever you just want to change something simple, like the margin or padding, is annoying as well.

This way I get utility classes with consistent naming (which are already documented) and I can still use regular CSS whenever multiple styles belong together. To me it's the best of both worlds.

Thread Thread
silvenon profile image
Matija Marohnić

Your method sounds great, looks like you found what's working for you, it's a good example of successfully mixing technologies 🙂 Regarding sharing config values, in case you didn't know you can also do that with the theme() directive as well, but of Custom Properties are dynamic and native, so probably a better choice. 🙂

Thread Thread
otijhuis profile image
Okke Tijhuis

Thanks :). The theme directive is indeed an option but I prefer not using any tailwind directives whenever possible.

In the end everything is about figuring out what works for your situation and what trade-offs you're willing to make. No technology is perfect. Something might be a perfect fit though, if you don't care about any of the trade-offs that were made. Unfortunately I see many people picking technologies based on hype, preferences or emotion alone.

Collapse
moopet profile image
Ben Sinclair

Agree.

Reason 1 and 2 get quoted to me when I try to argue my side, but really I don't see the benefit. If you want to make a rule for header > nav that uses things like big-white-text in its @apply rule, that's fine, but you can already do that with preprocessors like Sass. Tailwind being able to do things that we've been capable of doing for years isn't a selling point as far as I'm concerned - people don't really do that in the real world, and its selling point is that it's so much easier to do things in the terrible way everyone actually uses it.

Reason 5 is the big one for me.

I’ve written a few thousand words on why traditional “semantic class names” are the reason CSS is hard to maintain

I don't understand this. I've seen other FE developers in my various jobs make a total div-soup mess with inconsistent, non-semantic and redundant class names being the hooks for everything and I've managed to rewrite them into something semantic in fairly short order. If you need everything to be in a succession of wrappers I think that's a massive smell that you're doing something wrong.

Collapse
vahlcode profile image
Valentine Elum

Writing my own CSS is for me. There is this joy I derive from it!

Tailwind still an awesome project if you can deal with the reasons above. Some of them can be addressed by the creators though.

Collapse
andrewmcodes profile image
Andrew Mason

To me it’s really a shift from Bootstrap. Almost every production app I’ve ever worked on ultimately has a bootstrap theme underneath all of the crap they layered on top over the years. The other issue is the jquery plugins these themes are written on are mostly unmaintained and written in a flavor of JS that causes issues with the type of build systems and tools that are now standard.

You’ve got great points as usual, but the reality is most teams don’t write code like and most developers only know where to find the answers to layout issues vs a deeper understanding of HTML & CSS.

Honestly I view Tailwind as a gateway for most teams. They don’t want to write css but they’ve seen the pain of pulling things off the shelf and want to try something else. Tailwind is great if you’re writing components and it brings them much closer to the type of code you’d like to see vs the opinionated all in one tool like Material and Bootstrap were (I know they have both changed a lot as well).

I do feel this was a bit of an unfair jab though:

And Bootstrap at least provides an open-source component library for free. If you use Tailwind, they ask you to pay for it.

Tailwind has always been very clear that they are a utility library, not a full fledged framework. No one is forcing teams do use it and I think as a community we should be excited they’ve been able to still put out their work for free and make money at the same time. And to to be fair bootstrap sells themes and the bootstrap theme economy is still massive.

¯_(ツ)_/¯

Regardless I think people should definitely judge for themselves whether it will work for them or not and not follow the crowd and I applaud you for doing so.

Collapse
jaredcwhite profile image
Jared White Author

Thanks for your thoughts Andrew. I think for me the disconnect there is I totally get why people like to use Tailwind for rapid prototyping. The thing is, if I'm going to pick a CSS framework to use for rapid prototyping, I don't want to write all my components from scratch, I want them already there for me. If I have to do the work of writing a ton of components, the value of using Tailwind to do so diminishes rapidly. Maybe I would feel differently if I were in the PSD-to-HTML business or something?

Collapse
alexmartinfr profile image
Alex Martin

I understand you aren't interested in the paid optional TailwindUI component library. It's not for everyone.

But it isn't the only way to get ready-made Tailwind-styled components if you want them!

Check this free components repository:
tailwindcomponents.com/

🙂

Collapse
gsarig profile image
Giorgos Sarigiannidis

I'm on the same boat. I didn't find Bootstrap fitting for my needs a few years ago and I have the same feelings about Tailwind too (I too, have written my views on the subject in a post of my own a few months back).

My main concerns with such frameworks, besides the spaghetti HTML that you mention, have to do with the fact that they can become an obstacle if you want to implement something more complex.

Most importantly, though, you end up learning the framework instead of the underlying technology, so if at some point Tailwind becomes obsolete in favor of a new kid on the block, everything you've learned is useless. Learning actual CSS, on the other hand, will always be relevant, unless CSS itself somehow becomes irrelevant.

I could accept the tradeoff if writing CSS was so hard. It's not, though, and I find no real value into using class="flex" in the HTML instead of display: flex; in the CSS. Quite the opposite, as the latter offers much more control. Especially with tools like flexbox, grid, custom properties, and CSS preprocessors, I find frameworks to be more restrictive than helpful - at least for my needs.

Obviously, in the end each one should choose what makes them more productive, but it's always good to have a view of all the angles before you decide.

Collapse
viorelmocanu profile image
Viorel Mocanu

Wonderful article, Jared!

Let's face it: most of the people loving utility-first CSS don't really remember csszengarden.com/ and what it stood for back in the day. :) And leaving melancholic issues aside, Tailwind is great for rapid prototyping and developer-heavy teams that need to churn out loads of content super fast with no substantial need for maintenance and future-proofing. What I love the most about it (compared to Bootstrap for example) is the fact it does tree shaking of sorts and leaves only the CSS you actually use in the production package.

But that's pretty much it. For large-scale enterprise-level projects, I would go out on a limb and say vanilla CSS (including variables) + SASS is the only way to go if you don't want to have massive headaches with maintaining everything going forward.

I'd add from experience that with a very particular way of writing all media queries mobile-first (with min-width only) directly inside the element they modify (respecting the cascade) gets you the clarity and atomic precision you need when making highly responsive, complex web apps. The sheer elegance of copy-pasting the element class from the browser inspector into the SASS file and reading all the ways that one element adapts to all resolutions in one scan of the eye is what saved a lot of time on some of the projects I've had the pleasure to impose coding standards for.

Collapse
stikoo profile image
Alastair Hodgson

No, we old timers haven't forgotten what CSS Zen Garden represented (I built one!), we just understand that the principle of one HTML file many Stylesheets was never really practical in the real world of corporate development (at least not in the hundreds of large scale projects I've worked on).

I disagree on your point about Tailwind not being suitable for large scale projects, I've lead, architected and produced big enterprise websites using vanilla CSS, Bootstrap, Foundation, LESS, Ruby SASS (ouch) and Node SASS and co. For a good few years I boiled it down to Node SASS + BEM and it "worked". But I always had problems with it scaling up. Trying to keep things DRY, reusing components, all those best practises etc ultimately failed as the codebase gets out of hand, component count gets silly and attempts to try and make flexible components results in out of control BEM modifiers and specificity hell. It's almost impossible to avoid this when you work in large multi-channel teams.

I don't like fragile codebases and with Tailwind, I've found I don't get that, if anything it scales more easily, it works at prototype level because it's fairly quick to write, but for me it excels at scale where multiple devs can work on a project without fear of breaking things.

As for maintainability, I will swap jumping into a custom in-house CSS frankenwork (I can call them that, because I've unfortunately played major roles in creating them :D)
for a predictable tailwind codebase any day! The consistent language and style really helps shift between projects.

I love CSS, made a career out of it, I would consider myself a master of CSS, but I think Tailwind really helps with some of the pain points of large CSS projects and no amount of CSS custom properties are going to fix that.

I don't understand arguments about

soup either as I will always strive to create semantic well formed markup with or without Tailwind, I think one of the major problems with web development these days is that the art of creating great HTML has kind of been lost a little.

What I do know is that someone, somewhere will create something else in the future that solves all of our CSS woes and we'll be having these same discussions all over again soon :D

Collapse
jaredcwhite profile image
Jared White Author

Good points all around. I should point out that, regarding "it does tree shaking of sorts and leaves only the CSS you actually use in the production package" — you can do this with any CSS framework via PurgeCSS. I think Tailwind popularized the technique because you have to purge when using Tailwind. 😏 But you can purge with Bootstrap, Bulma, or any number of other frameworks.

At the rest of sounding like a broken record, you mentioned churning out loads of content super-fast with no need for future maintenance—so here's the deal: if Tailwind specifically advertised itself for exactly that use case, I'd be cheering from the bleachers. Go to town! Churn out that content, pat yourself on the back, and call it a day.

But to think Tailwind is the solution to long-term, multi-year projects where you want your code to be clean, lean, and mean…it's bananas to me.

Collapse
viorelmocanu profile image
Viorel Mocanu

PurgeCSS is wonderful but it's a very missable extra step at the end of the project if the team doesn't have this reflex built into the workflow. The fact that you can purge (and you should purge) doesn't mean everybody does it, unfortunately. Just take a look at the top 1000 sites by traffic (according to e.g. Alexa). Or the 40% of the Internet that's WordPress-based. Things are better than they used to be but are still way off the ideal.

I completely agree with your point of view regarding Tailwind. Cheers for writing this article! :)

Thread Thread
jaredcwhite profile image
Jared White Author

Yep, Purge CSS is a cool thing to have, but there are a lot of subtle edge cases and bugs that will trip folks up, including me! Not a set-and-forget solution.

Collapse
viorelmocanu profile image
Viorel Mocanu

P.S.
By the way, I found an unexpected (somewhat narrow) benefit of Tailwind or utility-first styles in general, which derives from the notion of rapid prototyping: if you're doing A/B testing using Google Optimize and the like, you need to write exactly zero CSS in order to create a completely different page design "in situ" (read: directly in Optimize's interface) because you can reuse those horrible utility classes and be done with it in the HTML alone.

Collapse
stikoo profile image
Alastair Hodgson

Until you try to use a class that has been purged :p

Collapse
melissamcewen profile image
Melissa McEwen

Sounds like a lot of the objections I have. To be fair a lot of my other objections were answered in this excellent post In Defense of Utility-First CSS. I'm not sure where I stand now. I know I wish Tailwind had more ability to be able to convert from Tailwind to something else. It's a big reason I didn't buy Tailwind UI even though I bought the Refactoring UI book. I work in devrel where I will often make demo apps but I don't want a lot of stuff in them besides what I'm trying to demonstrate. I don't want to set up a bundler either and Tailwind CSS doesn't work great with a CDN/just as a simple stylesheet because it's HUGE.

For now I've been using a lot of "classless" CSS "frameworks" like Sakura.css.

Also it makes me glad I'm not a front end dev anymore 😂

Collapse
jaredcwhite profile image
Jared White Author

The link there is a good overview of the "pro" side. I think what's really changed the game though is the rise of CSS variables, thereby rendering the objection to inline styles moot. For example, in the section Inline styles allow you to do anything you want. it shows putting font sizes and padding and such in a style= attribute. Everything's hard-coded. That's bad. But now it doesn't need to be hard-coded! You can put style="font-size: --var(size-lg)" or style="color: --var(color-primary-500)" etc. And of course it scales up to regular stylesheets or even CSS-in-JS techniques.

So, in a sense, you can have your utility CSS cake and eat BEM too (or some such methodology), without having to define a thousand utility class names. That's how I like to look at it anyway.

Collapse
dansvel profile image
dan

i surely can learn css,, i understand a bit,,

but choosing a color is hard to me,, need to knkw what hex color everytime i need coloring text or background,,

tailwind help me to simplify of doing that,, in same color i can use 9 sub-color

i even dont know what hex is, i can use text-green-400 hover:text-green-600 for my styling my link

if only pure css can do it too, may be i'll learn more,,

Collapse
jaredcwhite profile image
Jared White Author

Tailwind has an awesome color palette. Even Shoelace, the component library mentioned in the article, has adopted colors from Tailwind. I think you could maybe import Shoelace's base stylesheet and use their CSS variables for colors, even if you don't use any of their components! 🤔

Collapse
dansvel profile image
dan

oh,,,
so i can use it like this,,?

import "something"

body{
  background-color: var(--gray-100);
  color: var(--gray-900);
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
jaredcwhite profile image
Jared White Author

Exactly — you'd just reference the relatively small Shoelace CSS file of all the variables. Here's an overview of the colors: shoelace.style/tokens/color

Thread Thread
dansvel profile image
dan

wow,, nice to know,, thanks

Collapse
syntaxseed profile image
SyntaxSeed (Sherri W)

Great analysis.
I have yet to come upon real problems with semantic, component based CSS. I've been curious about Tailwind, but it seems to be the opposite of what CSS is meant for.

I think it's totally cool for people to like or dislike a technology & discuss the why. Don't know why people get so defensive about it.

Collapse
bezpowell profile image
BezPowell

I'm 100% in agreement. I've always used semantic CSS, as the message when I was learning was always styling should be separated from content.

Any form of utility based CSS seems to be in violation of that. If I use classes like 'bg-gray-100' and 'text-lg', then later on decide that the particular element is going to be differentiated using some other means I would either have to rewrite all my markup to achieve that, or to re-write the styles so that they now do something totally different from what the name suggests.

I definitely see the benefit of utility classes for rapid prototyping, but the future maintenance burden and loss of semantics seems to outweigh those advantages for me.

Collapse
wout profile image
Wout • Edited

Great post, Jared! Exactly my feeling. It made me cringe — such a mess it makes of your html. I did use it in a Rails project for a client and found myself @apply-ing a lot to keep things clean, which kind of defeats the purpose of utility classes.

While not ideal, BEM still works well for me. Especially in combination with view components in Rails.

Do you know Cube CSS? I haven't used it, but it's something I might consider for a future project.

Collapse
jaredcwhite profile image
Jared White Author

I'm not super opinionated about naming methodologies… I think having one is more important than any particular one. Lots of good ideas in CUBE.

Collapse
jaredcwhite profile image
Jared White Author

Interesting that you think it's my job to prove to you that you can write maintainable HTML and CSS. The burden of proof is on the "utility class" proponents to prove that their methodology is better, and I'm not convinced. 🤷🏻‍♂️

Collapse
dbot79574694 profile image
Danny

I have just recently started using tailwind and I really like it. I see a lot of comments saying it's good for prototype but not much else. I work on projects with a lot of people and I have a different experience.

There is nothing mandating the use of utility classes and they have no impact on the resulting build after being shaken / purged. So therefore combinations of both are possible, without requiring writing classes for both the specific and generalized elements. They ultimately refer to the same values, which is where things went messy in the past.

Also I define configuration variables in javascript for tailwind vs sass. Which means they are available to my apps (Like querying responsive images for breakpoints / defined media query components), but I digress.

I'm going to use an example from one of the other comments.

If I use classes like 'bg-gray-100' and 'text-lg', then later on decide that the particular element is going to be differentiated using some other means I would either have to rewrite all my markup to achieve that.

This is interesting to me, because I think this is actually where tailwind is a pro and not a con.
Lets throw in a media query into this also and look at the different ways to implement this.

Tailwind:

<p class="bg-gray-100 md:text-lg lg:text-xl">Thing</p>
Enter fullscreen mode Exit fullscreen mode

or extracted to a class...
As you can see, this is starting to look like common.

<p class="thing">Thing</p>
Enter fullscreen mode Exit fullscreen mode
.thing {
    @apply bg-gray-100 md:text-large lg:text-xl;
}
Enter fullscreen mode Exit fullscreen mode

or extracted to the components layer to preserve specificity ...

@layer components {
  .thing {
       @apply bg-gray-100 md:text-large lg:text-xl;
   }
}
Enter fullscreen mode Exit fullscreen mode

vs.

Common

Let's assume sass with some mixins for support.

<p class="thing">Thing</p>
Enter fullscreen mode Exit fullscreen mode
.thing {
    color: $bg-gray-100;
    @include breakpoint($md) {
       font-size: $text-large;
    }
    @include breakpoint($lg) {
       font-size: $text-xl;
    }
}
Enter fullscreen mode Exit fullscreen mode

Back to question,

Differentiated using some other means I would either have to rewrite all my markup to achieve that.

Let's say the text becomes small here for just the medium breakpoint, otherwise it's the same background colour.

Let's change the markup. 🤷‍♂️

<p class="bg-gray-100 md:text-sm">Thing</p>
Enter fullscreen mode Exit fullscreen mode

vs.

<p class="thing-2">Thing</p>
Enter fullscreen mode Exit fullscreen mode
.thing-2 {
    color: $bg-gray-100;
    @include breakpoint($md) {
       font-size: $text-small;
    }
}
Enter fullscreen mode Exit fullscreen mode

or worse, this has been the common approach to these kinds of things:

<p class="thing thing--small">Thing</p>
Enter fullscreen mode Exit fullscreen mode
.thing {
    color: $bg-gray-100;
    &--small {
        @include breakpoint($md) {
           font-size: $text-small;
        }        
    }
    @include breakpoint($md) {
       font-size: $text-large;
    }
    @include breakpoint($lg) {
       font-size: $text-xl;
    }
}
Enter fullscreen mode Exit fullscreen mode

The old approach would require me to search the entire project for previous instances of .thing-2 to make sure it didn't already exis and also if it had conflicting rules where it would modify my actual intent of what I wanted this to look like.

This would result in much larger css, and much more complicated to understand.

Collapse
paceaux profile image
Paceaux

I haven't used Tailwind, but I have heard lots of hype. This is incredibly insightful as it's a reasoned criticism. With what you've shared, I can add some additional criticisms.

I've worked in the content management system space for 12 years, 10~ as a developer. I can say that, based on what you've shared, Tailwind wouldn't play nicely with an enterprise CMS.

An enterprise CMS is likely "detached" from the web site/application; they are two separate codebases. The website consumes content from some API or repository where there may be some sort of relationship between content and presentation of content... basically I have one "article" that may look like four different things, depending on where it goes.

I often have a server-side MVC app whose job it is to render these pages, and that app is usually written in .net. This means there's a division of labor where front-end people are writing a "static" version of a component and a back-end person is slicing up the HTML for the MVC app.

Tailwind would not play well for my line of work because it doesn't separate concerns: It's putting presentation rules in markup where they could exist collectively in styles.

A very common scenario I deal with is "conditional content"; if a subtitle is present, the title must look differently (reduced line-height, margin, etc).

The Tailwind approach means that my back-end developer must write logic around my <title> to add some classes, but on account of the presence of a <subtitle>. This means I have to write a clear business rule in my markup to explain to the back-end developer how "conditional classes" work.

Additionally, because Tailwind wants a crapload of classes, this means that, potentially, I have to write a crappierload of documentation to explain to the back-end dev how they're used.

Add to this that, Tailwind's desire to offload all presentation work to markup, this means that my client requesting a change to something "small" like a subtitle requires two codebases to be touched and tested, since every change requires me to update the .net application.

Tailwind seems to be useful for scenarios where the front-end developer owns the markup and there isn't a need for multiple presentations of that markup.

Collapse
codyseibert profile image
Cody Seibert

Agreed, and the core issue is you’ll never know when you may need multiple presentations, so don’t code yourself into a corner and keep your code flexible

Collapse
clekstro profile image
Curtis Ekstrom

If you use Tailwind, they ask you to pay for it.

Please clarify/retract this. They sell a paid product, not the framework. And they've reinvested much time/effort/money back into the framework thanks to the success of that product, which is great for everyone.

Collapse
jaredcwhite profile image
Jared White Author

I was clearly talking about component libraries, as I'd just said that Bootstrap comes with one for free. If you use Tailwind, they ask you to pay for it. 😅

Collapse
clekstro profile image
Curtis Ekstrom

If you want high-quality Boostrap UIs/components similar to Tailwind UI, they ask you to pay for it: themes.getbootstrap.com/official-t.... None of this changes the fact that leaving the "UI" off of the name can make people think they have to pay to use the CSS framework, which is patently false.

Collapse
tillsanders profile image
Till Sanders

Great post! What I was missing though is the cascade. Tailwind completely ignores it to make maintaining CSS simpler. I understand where this is coming from, but while the cascade is complicated, it's also the most powerful feature of CSS and ignoring it just leads to redundancy. I completely stripped a project of Tailwind after realising this problem. I had a complex component that would be displayed in numerous different color themes. A font color here, a border-color there, a background-color on focus there. Nightmare with utility classes, but so simple using the cascade.

Collapse
jaredcwhite profile image
Jared White Author

The C in Cascade is a feature, not a bug. Can it be abused? Sure! So can classes and methods in OOP. Doesn't mean we just throw up our hands and run away from OOP. CSS variables are another great addition to the cascading concept.

Collapse
anthonycook profile image
Anthony Cook

I used Tailwind for a while but ditched it because all my sites/projects ended up looking too visually similar. That’s not to say you can’t make unique websites with Tailwind but most of the time I can look at a website and instantly tell it’s been made using Tailwind. We kinda had the same issue in the bootstrap days, it’s too easy to just stick with the default colour palette, shadows and sizes etc. Kinda kills creativity.

Collapse
steffan153 profile image
Steffan153

Idk, you might be confusing Tailwind with Tailwind UI?

Collapse
anthonycook profile image
Anthony Cook

Just regular Tailwind, people seem to go with the same shade of "Tailwind" purple or the minty green colour (usually on buttons or hero backgrounds). That combined with the more subtle stuff like the preset drop shadows and padding/margin spacing makes it easy (at least for me) to see when a site is using Tailwind.

Thread Thread
steffan153 profile image
Steffan153

Actually, after a few weeks I had the suspicion that Hashnode was using Tailwind. I looked and it was. xD

But based on my judging, the "Write a post" button on dev.to looks kinda Tailwindy, which it isn't.

Collapse
jmau111 profile image
J.

Very interesting post.

And as an added bonus, writing all your CSS files with @apply everywhere basically means you're not learning and authoring CSS. You're authoring Tailwind.

Undeniably. I think it's a niche market, and indeed, you must know CSS before using it. To me, it's just a tool, lighter than bootstrap, that can help you delivering. For now, I consider it as a nice solution when I lack time.

Nobody forces you, and if you (I'm not referring to anyone here) read and see it at face value, or if you use it everywhere, just for the sake of using it, then it's just hype, then you cannot be more wrong.

Agree with you on the div/span-tag soup too. It is a concern.

Collapse
tombohub profile image
tombohub • Edited

I like to see immediatelly what css is applied to the element. Save so much time going back and forth between files. Dont care if it's ugly. I even made an app to generate color palette for tailwind Palettolithic. That's how much I love it

Also in vscode with addon it goes so smooth autocompletion and CSS preview, not even thinking about it. No need to remember bunch of new tags or other stuff.

Collapse
jaredcwhite profile image
Jared White Author • Edited

Separation of concerns. There's a reason we shy away from putting SQL queries in controllers on the backend. We don't put HTTP routing in view templates. We don't put global environment configuration in database models.

Same on the frontend. HTML is about conceptual structure, text and multimedia, semantics, intent, accessibility, behavioral cues, metadata. It's not about color, shadows, typography, borders, outlines, shades, patterns, textures, layering. There's a reason we dropped tags like <center> and <font> and <marquee> (yikes!), while elevating <em> and <strong> over <b> and <i>. There's a reason we don't want to use <table> and related tags to lay out page sections.

The history of HTML has been a slow march towards a better vision of a universal "hypertext markup language". The way I see it, turning it into merely a box of crayons is going backwards, not forwards.

P. S. I like your tool. That's really cool. Any possibility of a :root CSS variables export? 😁

Collapse
tombohub profile image
tombohub • Edited

I agree with you on point of SQL, views etc to have separation of concerns when it comes to functional aspect, but I believe in HTML sense it's not so important to have that separation.

When we design website we are making visual part. HTML tags, together with CSS are that visual part. Most likely you are not just writing

and buttons, but they have some kind of visual appearance. So, if person takes one place to look how website looks visually in one place, like web page, then I think it's ok to also see the whole code that affects that visuals in one place.

Me personally, I just find it easier to have it like that instead of scrolling up and down CSS file, especially if it's not my code. Although with VScode addon you can find it easily. We have tools to make life easier for us, we should use them.

Re tool: Thanks man! Yes, I was thinking just the other day I should add CSS export too. Yeah it's on the todo list, I'll ping you when it's finished 😁 👍

Thread Thread
jaredcwhite profile image
Jared White Author

Cool, looking forward to it ☺️

Thread Thread
tombohub profile image
tombohub

hello my friend, as promised, now you can generate css variables from color palette: palettolithic.com/

Thread Thread
jaredcwhite profile image
Jared White Author

This is fantastic! 👏

Collapse
okikio profile image
Okiki

I feel like tailwind is often misunderstood. To me tailwind isn't really meant for production its meant for fast prototyping and development. If I want to make a clean and effective layout I use tailwind for general layout, I then convert all those classes and @apply to proper css and simplify my stylesheets, this allows for fast layouts and forces me to take a good look at my code when finalizing for production. I generally avoid using web components unless it's absolutely necessary, I use pug when rendering my site, I use pug mixins for components, and sass for styling. If a certain component requires web components, I again use tailwind for prototyping and then optimize the styles and classes for production.

Collapse
tillsanders profile image
Till Sanders

That might be a valid point! But having recently converted a project from Tailwind to vanilla CSS, I don't really see the benefit of prototyping this way.
Though I must admit that might be because I was using Vue Single File Components, so I was essentially only moving Tailwind classes further down in the same file and translating them to vanilla CSS.

Collapse
okikio profile image
Okiki

Tailwind has all the basic utility styles I personally use e.g. padding, margin, background-color, font-size, font-color, etc... making it incredibly useful for prototyping quickly. In order to make tailwind faster I disable all complex styles and switch to using vanilla css for box-shadow, transitions and transforms, making my development process fast.

Collapse
davidhellmann profile image
David Hellmann

Tried it few times and now I think I use Tailwind for my next Projects. Don’t know why Apply is a huge topic here. I use it just for basic stuff (global styling).

I think when you go with Tailwind the only way is to use it mostly directly within the class attribute and not in the css files with apply.

But I can understand your points and for sure they’re not wrong.

jaredcwhite profile image
Jared White Author

I appreciate what you're trying to tell me. Look at the verbosity of all that CSS! Why do we have to write all that? Geeez.

But the crux of the matter is I likely would never write so much CSS in the first place for what amounts to a "one-off" bit of content. Is there a way we can compose this content out of simpler, more generic components? If so, we write the components' CSS once with an appropriate degree of customization, and then it's useful in many different scenarios. I have no problem with writing verbose CSS in such a case. (Let's all agree that append-only global stylesheets is Not Good.)

I would also take exception to your assertion that HTML is meant for machines, not humans. I happen to think most programming languages most of the time are in fact intended for humans. That they're machine parsable and executable is simply a bonus.

Collapse
tomhermans profile image
tom hermans • Edited

Nice write-up. You highlighted for me 3 and 4.
Yes, more reliance on custom props (what I usually do).
But a few others I attribute more to preference or the way-you-work-with it. No incompatible css files here..
1 is preference or more "can't stand the look of it" imho
2 You shouldn't use @apply, it's actively discouraged
5 if the argument is webcomponents, you can throw this to every css framework or even bespoke css imho.

TW isn't perfect, but I must say that of EVERY project I've worked on, and usually they hire me to fix stuff, this has been the most resilient I've come across. No surprises knocking over stuff in some page or component when you're making changes to another..

But, indeed, it can be better, it's not for everyone, and I was never the one to bet all my horses on some tech.
It DOES help me get 80% done in 20% of the time, freeing my hands for more fun stuff. (who likes to write the same class declarations over and over again).

Collapse
jaredcwhite profile image
Jared White Author

"You shouldn't use @apply, it's actively discouraged"

Huh. That's the reason we are even using Taildwind on the project I referenced in my article. 😂 Nobody wanted to build a bunch of React components with utility classes sprayed all over the markup everywhere. @apply was the saving grace.

Collapse
opensas profile image
opensas

Hi tom, could you tell me why is it discouraged? and perhaps some link discussing it.
It also smells to me like a bit hacky but I don't know what's wrong with it.
Oh, and I couldn't ifnd a way to use @apply from a component and still be able to override it (I don't know how to use the @layer component directive from a component) More details here: stackoverflow.com/questions/690597...

Collapse
dreitzner profile image
Domenik Reitzner

I get your points and personal preference. Very well written.
I do not agree about the web components part though. I'm not so sure that they will have such a strong influence in future web development.
Definitely agree about the CSS vars (I use them not often enough myself, probably because for most projects or clients still want us to support IE somewhat😅).
Personally I'm a fan of utility CSS styles but we shouldn't go overboard either 😉

Thank you for taking the time to express your points! 👏

Collapse
sheriffderek profile image
sheriffderek • Edited

Amen.

Reason 1? Regular CSS is just better in every conceivable way than some insane 2009 abstraction layer that's completely unreadable and at odds with modern layout necessities and techniques.

codepen.io/sheriffderek/pen/QWwyJmB

Collapse
sheriffderek profile image
sheriffderek

Go ahead and use it though. I just know that I'll quit writing HTML completely before I ever working on a project with that markup. And that's not with any handlebars or other attributes...

Collapse
stiffroy profile image
Stiff Roy

You are awesome. I was just to write an article about why I wouldn't use Tailwind and I found yours. I think people are engraved so much into other things that they sometimes overlook the basics. Just 2 points from me:

  1. Instead of writing such a big class name collections, why not use the style tag?
  2. When the frontend guys are literally fighting for decreasing the JS file size to 2 bytes (which is loaded asynchronously) why are they so much interested in increasing the base html file size by adding this junks to the class name?

Though there are more, I will leave it here. I think all the discussion comes to an end with the official declaration of it's creator that - “Best practices” don’t actually work. May be we need to forget everything and need to wait for a new "Best Practice" manual soon. May be it will contain some suggestions to the browser developers about how badly the DOM is organised or used... hahaha. Who knows?