DEV Community

Ben Halpern
Ben Halpern

Posted on

Is the Tailwind approach a big step forward for CSS or just-yet-another-thing?

I've really seen Tailwinds take off lately in "marketshare" as well as "love-share".

On the other hand, the CSS ecosystem has been in mayhem for years...

I find the Tailwinds utility-first approach to be a really pleasant way to work with CSS, and CSS and pleasant are rarely used together in a sentence.

...But we've been here before in so many ways. I'd love to get folks' opinions on the CSS space.

Top comments (65)

Collapse
 
nickytonline profile image
Nick Taylor

Some good feedback came out of this post.

TLDR in the comments in that post seems to be you either love it or hate it.

Collapse
 
shaijut profile image
Shaiju T

Why tailwind is better than bootstrap ?

Collapse
 
turbopasi profile image
Pascal Lamers

You can't compare tailwind with bootstrap . Tailwind is a utility first framework, which does not give you ready-to-use components. Bootstrap mostly gives you ready-to-use components.

Thread Thread
 
5422m4n profile image
Sven Kanoldt

on the other hand bootstrap has this aspect of css utilities. So you can take out only the scss of bootstrap and use it with whatever react / angular / whatever framework and you get the quite decent bootstrap styling. Only by reusing their css vocabulary.

Collapse
 
mtpiercey profile image
Matthew Piercey

Here's my two cents (rounded to a nickel since Canadian pennies are no more...):

Tailwind is super useful as opposed to a lot of other frameworks, IMO, because it doesn't have a pre-determined philosophy. Bootstrap/Foundation/Bulma/Materialize/Vuetify & co. say "this is a button" or "this is a navigation drawer."

That kind of paradigm is useful when you don't have those ideas floating around in your head already, or you like the way they do it. But what if you want to change the margins, padding, font size, or what have you of one of those components? I'm working with Vuetify right now, and I can say first-hand that that annoyingly means a lot of !importants in my CSS...

Tailwind (other than the new Tailwind UI, which looks intriguing) is basically just like writing CSS, except most of the normal/mundane things have an easy class (that doesn't come with any side-effects, baggage, or other styles). Want to have a button get bigger on hover? Add transform hover:scale-105 to the classes. Boom. Done.

But it doesn't replace CSS, in my opinion. There are some things you just can't break down into reusable classes like that. Like animations, or custom media queries (though Tailwind does come with an ample amount of customization for the latter), or - dare I say - some kind of browser hack to fix that annoying little glitch that happens to the hover styles on last year's version of Chrome...

To me, SASS is the future of CSS, but Tailwind means you can write less Sass, especially for reusable things.

Though, it has its limits. One is fairly obvious; you're still writing a whole bunch of styles, just not in the style block, but right in the HTML. You can easily get a class list that takes up several lines, or trails off beyond the horizon of your editor like a minified, inline SVG. Tailwind does use the @apply directive of Sass to apply a lot of stuff as mixins, so that can be avoided to some extent.

The other, of course, as already mentioned by my fellow commenters, is that you really need PurgeCSS or something like it when you're using Tailwind. It just adds a bunch of mostly-unused bloat to your bundle size otherwise (to the tune of a few hundred kilos, if you aren't careful - and even sometimes if you are). And, at least for me, Purge is almost more trouble than it's worth. Almost.

Bottom line here is that it isn't a magic bullet. It solves a ton of problems, but it introduces a ton of potential challenges. At the end of the day, you can't really beat proper modularization (via Sass or scoped styles in Vue components or what have you, perhaps) of styles and class naming conventions that make sense. Tailwind brings a lot to the table, sure, but it really brings a lot (by way of overhead and build process shenanigans). It ain't magic, folks (but if you like it, you'll really like it).

Collapse
 
jsn1nj4 profile image
Elliot Derhay

Just a minor thing, but I believe Tailwind's @apply is a PostCSS directive, even if Sass provided that directive first.

Definitely agree something like Purgecss is needed. Love Tailwind, but I'd have a hard time shrinking my production CSS otherwise with the shear number of variants.

Collapse
 
mtpiercey profile image
Matthew Piercey

You're right, of course (since Tailwind needs PostCSS to function properly for most applications). I use Nuxt, so I'm used to over-abstraction to the point where "it just works", so I tend to forget where things actually come from.

Thread Thread
 
jsn1nj4 profile image
Elliot Derhay

Nuxt is pretty awesome too (even though I haven't gotten to use it extensively yet). Love Vue!

Thread Thread
 
jsn1nj4 profile image
Elliot Derhay

Also, no worries. Was mainly mentioning for others who would read. I'm really glad Tw has this directive too. I haven't yet, but I have some Vue components I'm thinking of taking the Tw classes from and turning into CSS components—small things that make sense now that I've used Tw on this one project for a while. This directive will really come in handy in this case.

Collapse
 
rickmills profile image
Rick Mills

PurgeCSS is a must with tailwind. They actually added it as a built in feature in the latest release so it's super easy to get it up and running now.

I think this actually gives them a one-up on bootstrap now too as it does now mean that the out of the box compiled production css is far smaller than bootstraps.

Thread Thread
 
mtpiercey profile image
Matthew Piercey

Ah, I see! Thanks for the heads-up (I've been using 1.3, so I didn't catch that update). You got a point there; Tailwind + Purge (especially now that there's first-party support for the integration) is a winning combination.

Collapse
 
mikaelgramont profile image
Mikael Gramont

This is a pretty balanced take on it.

I agree with this especially: To me, SASS is the future of CSS, but Tailwind means you can write less Sass, especially for reusable things.

I think the way forward would be to write high-level SASS mixins (say, 'content-column') on top of low-level ones (say 'content-margin' and 'body-text'), and then once some of the high-level ones are used widely across an app, you could promote them to utilities like Tailwind's.

This would give you a good compromise: readable markup, centralized rules, a separation between component and utility, and last, it would save some duplication in the generated CSS.

Collapse
 
glennmen profile image
Glenn Carremans

I almost never do any frontend stuff, mostly backend or native Android, but with tailwindcss I was able to quickly throw together a nice design that was build responsive without needing to write a single line of CSS myself.

Adam Wathan (tailwindcss creator) is also taking this to the next level and looking for 2 people to join him fulltime.

Collapse
 
cescquintero profile image
Francisco Quintero 🇨🇴

Backend with same experience here.

I'm working on something personal and Tailwind saved me the work to write lots of styles I didn't have enough idea of.

It's simpler than Bootstrap (which is my default many times) and easier to use.

Collapse
 
hozefaj profile image
Hozefa

I think the idea of utility first approach is the way forward. This gives flexibility to the engineers to build UI's how ever they choose while leveraging the power of the utility. The utility updating under the hood allows to better browser support.

Collapse
 
giorgosk profile image
Giorgos Kontopoulos 👀 • Edited

I think atomic/utility/functional css is an interesting approach in writing css that was mostly misunderstood until tailwindcss came out with this specific implementation. It mostly makes styling components faster and frontend developers love it. On top of that can reduce the amount of the final css send to the browser and can benefit website/apps of any size. Facebook recently anounced how their new atomic css approach has reduced their css by even 80%.

I think tailwind it is here to stay and perhaps more frameworks will follow this paradigm.

Collapse
 
mikaelgramont profile image
Mikael Gramont

I would take the "Facebook reduced their CSS by 80%" point with a grain of salt.

There is no hard rule saying that atomic CSS will reduce your CSS by a large amount. It all depends on how the CSS was written in the first place (not to mention how the counting was done).

Imagine FB has 300 engineers working their UI (I don't really know). It's very likely that a lot of them will repeat the same code (BTW, this is what brought Nicole Sullivan to come up with OOCSS back in the day), and atomic CSS is likely to have a big impact here because there is so much CSS in the first place.

But on smaller teams, with 4 devs who know what they're doing? I'd be surprised if we saw more than a 15% reduction.

All of this is opinion, and I have no data to back it up, but I don't think this is a crazy argument.

Collapse
 
giorgosk profile image
Giorgos Kontopoulos 👀

Yes I usually take everything with a grain of salt. I am just pointing out the possibility and facebook example shows that if carefully planned we can have big reductions in css size.

In the case of tailwind the integrated purgecss plugin can help us reduce the css size but it is not always possible to actually use it and in those cases tailwind should be avoided or manual optimizations should be employed. Purgecss usually needs to scan all pages to see classes used to eliminate the unused ones which is not always possible especially on dynamic sites.

I believe will see tools and platforms finding ways to feed the used classes to purgecss to take advantage of tailwind powers. This is usually a painpoint of integrating tailwind with any existing platform/framework/project.

For me the main point from the facebok article in regards to css is that they addressed this by generating atomic CSS at build time. It would be nice if they open sourced this tool. Either way at least it has given food for thought to many excellent engineers to think of ways to do the same and will be seeing similar approaches very soon.

Collapse
 
xowap profile image
Rémy 🤖

Funny article where Facebook announces to the world they've discovered this new framework called React and they used it for their home page.

Though to me the only lesson we can get from there is that they trashed 16 years of legacy code written between vodka shots in order to use more modern practices and it improved a bit. I wouldn't draw any conclusion towards "atomic CSS" or Tailwind.

Collapse
 
ben profile image
Ben Halpern

I agree with this.

Collapse
 
reinoute profile image
Reinout

If Tailwind doesn't provide the utility class to do something, what's the recommended way to solve this? For example, adding a background image or add styles to a :before or :after pseudo element. Should you add a custom class?

That's where in my opinion these CSS frameworks fall short. They promise that styles are in 1 place (your HTML), but if you have to build a highly custom pixel-perfect responsive design you have to violate the principles they are based on.

Collapse
 
jonathans profile image
Jonathan Sundqvist

Personally, tailwind has opacity-25, opacity-50, opacity-75, but in this case I really wanted opacity-90. Usually when I'm confronted with cases like that I mostly just add that to my custom css.

The tailwind way of thinking is really useful.

Collapse
 
dawntraoz profile image
Alba Silvente Fuentes

I have gone through all the phases, I started with my own styles with CSS, I went through LESS, I tried with Bootstrap 3 and 4, then I moved to SASS to be able to create the class libraries in the companies I worked with and I stayed there. A new design would come and I would layout and add my named classes in BEM.

And suddenly, PAM, utility-first and I said 'wow, this is not going to be better than my own styles' and I start reading and discover that what I added in the inspector as property-value to add to my SASS class, now it's a class I can add in my HTML and the magic is done.

Honestly, I understand that there are projects that don't fit with this technology for x reasons, but my productivity has increased a minimum of 75% since I use TaiwanindCSS, I just can't love them more 😍

Collapse
 
sergix profile image
Peyton McGinnis • Edited

Big step forward. Quoting myself from my reply to Nick Taylor's post:

I was a little put off by Tailwind when I first looked at the examples in the documentation.

Why would I put all these classes in my HTML? Why wouldn't I just use Sass mixins?

But I decided to give it a shot, and oh man am I glad I did.

Once you start seeing patterns and memorizing the basic utility classes, it becomes an absolute breeze to style any component or section of your page might have.

I found it especially great for using flexbox, simply specifying flex and flex-1, flex-grow, flex-shrink, etc.

And the configuration and adding custom classes is very simple and intuitive once you learn it, which doesn't take long at all.
Again, it does seem off-putting at first, but as the docs themselves say,
You just have to try it.

Collapse
 
iamschulz profile image
Daniel Schulz

I think Tailwind has its place in very large, complicated web projects. You don't have to worry about the size and scalability of your stylesheet ever again.

However, it's not without drawbacks
The first is the added complexity. Tailwind isn't usable without Purging. You have to have a proper setup for your tailwind config, postcss, purge, and whetever your need in between. Setting up takes time and requires maintenance, especially as dependencies change.
Want to go crazy with wild grid layouts? Animation? Next-gen properties? You'll have to implement them in Tailwind by hand first, which kinda defies its reason. Do that a lot, and you'll soon feel like you're constantly fighting against your CSS framework.

Collapse
 
mikaelgramont profile image
Mikael Gramont • Edited

I'll play bad cop here because everyone seems to be playing good cop :)

  • "as a backend dev, I can do CSS!"
    So you can't write plain CSS but Tailwind works for you. Great news, more productivity is a good thing!
    But you still had to read Tailwind's doc and learn it, right? I'm guessing you chose that route because it felt less daunting than learning CSS from scratch. Could it be that a good part of the value you're getting is rooted in Tailwind's high quality docs that make it easy to learn? Compare that to CSS which does not really have a central place to learn? (check out every layout if you're learning layout).
    So to sum up: great if it helps you, but please learn CSS. Tailwind can be a great path to learning it in a "safe" way.

  • "naming is hard".
    I am both sad and angry that this is a thing that people bring up. I would argue that if you can't come up with a class name for an element, maybe it's not clear to you why it exists? Maybe it's an extra div you don't need? Usually when you write lean markup, names just spring at you. And... the author does not even bring this up! Let's forget about this one, it's more of a footnote than an argument.

  • "atomic CSS is the future"
    I agree that 5 years from now, atomic CSS will still exist and will still be going strong. But I guarantee you most people won't be using it. This is opinion of course, but so is the other argument.

  • I don't quite see why we can't move the utility approach to SASS mixins and keep the composition in *.scss files. This would be a good compromise IMHO. Yes this will lead to a little bit more code duplication in the CSS sent down the pipes, but Gzip is your friend, and...

  • I don't buy the "huge reduction in CSS" (see Facebook's recent post) argument. I think it won't lead to the same huge reduction in most teams with fewer devs and a lot less CSS. The total sum of my CSS bundles is in the 60KB range. That's not enough to cause me to question how I write CSS. It is for Facebook, but how many people are playing at their level?

;)

Collapse
 
moopet profile image
Ben Sinclair

I would argue that if you can't come up with a class name for an element, maybe it's not clear to you why it exists?

This.

Collapse
 
seangwright profile image
Sean G. Wright

My comment in Nick Taylor's post gives some background on what problems TailwindCSS tries to solve (spoiler! it's not trying to be the solution for every site/application).

Adam Wathan, the maintainer of TailwindCSS, wrote an article a couple years ago about the differences in CSS architecture that exist between traditional approaches (BEM, SMACSS) and atomic/utility approaches.

Here's that article: adamwathan.me/css-utility-classes-...

I recommend everyone read it.

Adam doesn't declare that one approach is bad and another is good. Instead he provides insight into what the constraints are of each and what use-cases each might be good for.

In the end he argues that most of the sites/apps he works on benefit from the approach provided by TailwindCSS and other similar libraries (Bulma, Tachyons, even Bootstrap's utility classes).

I think understanding why we should use TailwindCSS is as important (or more) as asking the question "does Tailwind make me more productive?"

And yes, I like TailwindCSS because it fits the type of work that I find myself regularly doing.

I think the key thought in the blog post from Adam Wathan (that I linked to in my other comment) is this (emphasis is Adam's):

The reason I call the approach I take to CSS utility-first is because I try to build everything I can out of utilities, and only extract repeating patterns as they emerge.

  • Naming things is hard, so don't force yourself to name things that don't deserve names yet!
  • Componentization is the process of identifying and codifying patterns of behavior, so don't componentize CSS when you don't even have a pattern yet!
  • Utility classes constrain by defining the limited set of options available, which is easier to reason about the next time you try to style a <div>, compared to the entirety of CSS. (We are freed to be creative through our constraints).
Collapse
 
etienneburdet profile image
Etienne Burdet

Thanks for sharing!
I do agry on not componentizing/abstracting too early and I have been a huge user of bootstrap utility-class… only to move away from it all over again.

When you have to maintain your app, you definitely don't want to be chasing if every single spacing utility has been changed correctly. A coherent system of named components greatly helps in that.

Collapse
 
seangwright profile image
Sean G. Wright • Edited

That's a great point and an issue I've run into myself.

The Pros of this approach are also the Cons! 😁

If I use these utility classes to style my markup, then I can change markup and classes in one part of the app without worrying about regressions somewhere else.

The utility class approach is resistant to unintended changes, which is a great feature 💪!

However, if I want to make the same change across the entire app, I'm going to have to do that manually because the utility class approach is resistant to intended changes, which means more work for me ☹.

So here's a question worth considering - what's more important to you, preventing regressions or refactoring quickly 🤔?

The answer to this question needs to be balanced with the other pros/cons of utility based classes already detailed.

One thing I've found helps mitigate the refactoring cost of utility based classes is componentization, not at the CSS level, but at the HTML level.

Client-side JavaScript frameworks (and even some server-side templating languages) excel at this. They are able to group blocks of reusable HTML into a 'component', which means some app-wide changes can be made in a single location.

Collapse
 
mikaelgramont profile image
Mikael Gramont

Thanks for bringing up the original article again. I read it back then, and seeing how popular Tailwind has become, it's good to see what prompted it in the first place.
Going down the article, you can't really help but be convinced that he's on to something.

Collapse
 
xowap profile image
Rémy 🤖

My personal theory is that Tailwind is a joke that nobody really caught.

A few arguments:

  1. If you're writing your CSS in class instead of <style> well so be it but you're still writing it.
  2. How exactly do you justify to yourself putting so many classes and copy/pasting so much code? That's not DRY, that's the middle of the ocean where Tailwind pushes you to.
  3. You need complicated tooling to use it right. Do we really need more tooling for something that is basically Emmet in class?
  4. But mostly, writing good CSS is about intent. I don't see anybody documenting their CSS but I put comments on every single CSS selector in my code to explain why they are here and why I made those choices. Same thing goes for variables, even if I never change the value, by reading an expression I can understand how I got this margin size. And you get absolutely no chance of doing that with Tailwind.

I'll sum this up that way: if you can't document it, why even bother using it?

Collapse
 
ghoststreetvitor profile image
ghoststreet-vitor

Tailwind is more than a joke. It's a terrible joke.

Collapse
 
drews256 profile image
Andrew Stuntz

I can't wait for tailwind to mature a little bit more. Tailwind feels like it really allows you to leverage the power of css without so much of the pain of following arcane naming rules, getting stuck into a framework, or not knowing what is going on with your styling.

Collapse
 
etienneburdet profile image
Etienne Burdet

It's very fast for solo building, but I have my doubts for long term maintenance, especially in a team.

If you don't use a some sort of component based approach, when you need to change the padding of every type of card, you're good to find them all by hand.

Even if you do code in components, some might be different but inherits common properties—cards padding still is the good candidate. Then again, you are good to find them all by hand, with no guarantee that everything with px-4 is a card.

And when coding components with scoped styles (Vue/Svelte…), I hardly use classes at all anyways, even utilities. Selectors are most often tags or ids. Values are either obvious, either some gobal variables.

Now the problem of coding in component has been known for years and is mostly tackled since bootstrap popularized it—altough… surprises. The problem of overall coherence and DRYness is solved with global settings and global classes as popularized by… yeah Boostrap.

I actually often end up rebuilding my little Boostrap from the bottom up everytime. First, do things in components with stupid selectors. Then, whenever you feel you are repeating yourself (colors, spacing, global class…) create a global class or variable. And voilà. It's just as fast, but much more guaranted to be coherent. I guess that makes me in the Sass camp?

Last one for the road: one more config file!🎉 _package.json, eslintrc, webpackconfilg, nuxtconfig, now/firebase _… and now tailwindconfig with it's very own fleet of arrays. Who said convention ? 😇

Collapse
 
moopet profile image
Ben Sinclair

I think it's a medium-sized step backwards.

I mean, it's only a small step backwards, but I'm setting it to "medium" since it's getting more momentum for some reason.

I think it's another example of people doing exactly the wrong thing. I guess it ties in relatively neatly with CSS-in-JS and all the other things I think are badong.

The only way that putting your style in your markup is ever going to help is if in the future we have AIs to do all this for us. Because it's back-to-front. It's worse for everyone.