DEV Community

Cover image for Why Tailwind CSS

Why Tailwind CSS

swyx on October 04, 2020

Translations: 中文, Português I'm not a Tailwind shill. I'm a Guo Lai Ren - someone who has changed their mind on it recently and am a happy user de...
Collapse
 
giorgosk profile image
Giorgos Kontopoulos 👀 • Edited

@swyx nice write up as always and I agree overall
I am personally getting my hands dirty with tailwind currently.

One objection though

Perhaps it was not clear to me or perhaps not clearly expressed but Inlining Styles reduces Naming is not clearly a benefit if you ask me.

If we let all those long arrays of classes that make up a tailwind component inside HTML in production we are trading difficult BEM naming for ease of changing right in HTML but we are also inheritting bigger (in size) HTML files and more difficulty in keeping consistent components.

I believe even in the docs it mentions that we are to extract those classes into other classes with @apply tailwindcss.com/docs/extracting-co... especially if we are to use them in more than one place and in order to reduce the HTML sizes. With this CSS file sizes should not go up much I believe.

It is probably the most controversial point about Tailwind and when people see it it does seem like adding styles in the HTML which we rightfully succeeded (as a community) to overcome a long time ago and this is the point that @nektro is making in a different comment in here.

If tailwind or a tailwind plugin finds a clever way to extract those arrays of classes into meaningfully named custom classes than it will be a step ahead of the competition.

Until than I believe either way of styling big codebases (with tailwind or without) is a test in organizational skills.

  • also a typo perphaps you have "known known" in the text
Collapse
 
swyx profile image
swyx

thanks giorgos!

no, "known known" is on purpose.

i dont agree with your point here. the point is that you can achieve consistent components through other means, and you should push styles down to the html element as far as possible. @apply isn't meant to be used extensively, according to Adam. in short, yes, we do want to add styles in HTML, that is what is so hard to accept because it goes against conventional wisdom.

Collapse
 
giorgosk profile image
Giorgos Kontopoulos 👀 • Edited

Shawn
Yes those are some nice TIPS from Adam in the video you linked to, and yes he does mention not overusing @apply (which I was not aware about) but that is a general statement and a recommendation but I still think it is actually to performance's benefit to use it as much as possible.

I don't like the idea of a component that is full of tailwind classes cluttering HTML and making it heavy in size. I would create custom app classes (using @apply) and add those classes as class values inside my component instead in order to create lighter HTML files.

Imagine a component that gets created 100 times in a loop with tailwind classes taking most of the HTML space. I would naturally want to use @apply to reduce html size and css size would not increase proportionately I believe (might be wrong).

I might be going against the flow or some might say misusing tailwind here but I think we ought to ourselves and the community at large to make our systems as performant as possible when we can.

Collapse
 
nektro profile image
Comment marked as low quality/non-constructive by the community. View Code of Conduct
Meghan (she/her)

goes against conventional wisdom

it goes against the fundamental structure of the web. html for layout, css for style, js for interactivity. if you wanna do it a different way, then web might not be for you.

Collapse
 
itaditya profile image
Aditya Agarwal

You write so clearly Shawn. I have seen these benefits myself but couldn't summarize it like you do.

I have only written one benefit that is bring your styles to anywhere
devadi.netlify.app/unpolished?id=4...

Collapse
 
swyx profile image
swyx

thanks Aditya! yes agree, however I don't think this is a big selling point bc I find whenever I bring anything anywhere I end up doing a lot of rewriting anyway. in other words I think this benefit sounds bigger in theory than it really is in practice.

Collapse
 
nektro profile image
Meghan (she/her)

Tailwind is just CSS-in-HTML though...

Collapse
 
weakish profile image
Jang Rush

Hi, I've translated your svelet for sites, react for apps and enjoyed the translation process. I am asking your permission again, to translate this Tailwind CSS introduction to Chinese. Looking forward to your reply.

Collapse
 
swyx profile image
swyx

you always have my permission, just do it :)

Collapse
 
weakish profile image
Jang Rush

Chinese translation published: nextfe.com/why-tailwind-css/

BTW, it seems that Theme UI changed their url architecture. theme-ui.com/home/ is 404 now. The new url is theme-ui.com now.

Thread Thread
 
swyx profile image
swyx

thank you! will update

Collapse
 
bitwombat profile image
Bit Wombat

This writing is excellent, thanks Shawn. Subtlely packed full of ideas that are deep-dives themselves.

My problem with Tailwind is that it's really a language. A language on top of two languages. And so I expect we'll have TailWind linters, TailWind re-formatters, TailWind toolchains, TailWind style guides, TailWind auto-completion... as a vetran of this industry, may I just say: SIGH :)

Collapse
 
swyx profile image
swyx

thank you so much!

yeah i hear you. that said, the alternative is really a custom "language" you cook up in your own team/company/projects, which is virtually guaranteed to have worse design, tooling, compatibility. people aren't just adopting this stuff just for the sake of it.

 
swyx profile image
swyx • Edited

no point discussing performance tradeoffs without actually measuring. if you want to do a benchmark I would be happy to take a look at it and help to publicize it.

Thread Thread
 
giorgosk profile image
Giorgos Kontopoulos 👀 • Edited

@swyx my point can be argued without actually measuring exact performance gain. Simple case mentioned above making it a little more concrete:

instead of multiple times adding the same tailwind classes to a card component extract the classes and use @apply them to custom class and use those in your html, after reusing card a 2nd time you already saved some of space for the html file the more you repeat the component the more you save on html space ... as simple as that.

If I get a chance I will create a demonstration but no need for performance testing.

Thread Thread
 
swyx profile image
swyx

nothing in perf is simple. how do you account for gzip of your html?

Thread Thread
 
giorgosk profile image
Giorgos Kontopoulos 👀

True gzip might be compressing and mitigating for all the repetition

Collapse
 
zoltanszogyenyi profile image
Zoltán Szőgyényi

Awesome article! I also started using the CSS framework more and more lately. Even wrote a small guide on how to use Tailwind CSS with PostCSS and the configuration file. Many make the mistake thinking Tailwind only means having lots of classes for an element, which is not always true.

Collapse
 
echoes2099 profile image
echoes2099

The Tailwind API surface area is big and constantly growing. It's understandable (it has to map all of CSS!) but also can be tiring to learn and keep up with.

This seems like a big downside. CSS-in-JS has a very minimal learning curve since once you spin up a component, you just use regular CSS to style.

I guess what's not said is, "Why doesn't CSS-in-JS scale?"

Collapse
 
kamalhm profile image
Kamal

Oh that BEM argument hits too close

Collapse
 
swyx profile image
swyx

dude it still haunts me. and for a long time I thought it was my fault for not getting it. now I realize I don't HAVE to give a shit about a flawed naming system.

Collapse
 
burntcaramel profile image
Patrick Smith

This is really well written! It captures what I have thought and tried to say and puts it into better sentences. (icing.space/2019/the-css-spectrum-...)

One benefit missing like Aditya says is that it doesn’t lock you into a JavaScript-only world. Also I think the performance can be greater without the overheads of CSS-in-JS. It also makes server-rendering of React simple as you don’t have to capture the styles that were generated. I go into the performance implications here (I’m sure emotion is faster than styled-components here) icing.space/2019/pure-styling-of-c...

Plus I think you can do some pretty neat stuff around TypeScript and improving the developer experience of utility styles with type safety and autocompletion: icing.space/2019/pure-styling-of-c...

I agree that with Tailwind the setup could be simpler. I’m curious around your thoughts of the generated CSS file size and whether the purge options work well for you?

Collapse
 
swyx profile image
swyx

thanks! purge works fine. I don't see the benefit of TS for tailwind bc I rather use the Tailwind VS code extension rather than bloating my typescript toolchain with a zillion classes. and I mention but don't elaborate the performance aspect of not tying to JavaScript, but I believe that perf discussions without doing a benchmark on a realistic app are pointless.

Collapse
 
ixartz profile image
Remi W.

Thank you for sharing your opinion about Tailwind CSS. I've also written a small blog post about Tailwind CSS and my thought at creativedesignsguru.com/why-i-love...

 
giorgosk profile image
Giorgos Kontopoulos 👀 • Edited

I never said I would ship this css code to every page regardless and perhaps it is my bad for not mentioning.

This css would be included only if the component is included but only once and not be repeated within each occurance of the component. In case of one instance of the component I don't have any gains but in case the component gets included multiple times (for loop, a listing page) the gains could be substantial.

Thread Thread
 
allsystemsarego profile image
ALLSYSTEMSAREGO • Edited

The unreleased Stylex library Facebook has developed referred to in the article above solves the Sublinear Scaling of CSS problem, without moving the problem to HTML like Tailwind appears to have done.

It identifies where the same styles sheet properties are reused across multiple components and generates the minimum number of classes nessesary.

This could probably be incorporated into the build process for tailwind.

< div className={stylex({
backgroundColor: 'blue',
color: 'black'
})} >

< div className={stylex({
backgroundColor: 'blue',
color: 'black',
fontWeight: 'bold'
})} >

Effectively renders to something like

.a {
backgroundColor: 'blue',
color: 'black'
}

.b {
fontWeight: 'bold'
}

< div className="a" >
< div className="a b" >

Collapse
 
silvenon profile image
Matija Marohnić • Edited

Great post! Very informative and much more relevant than the opposing one I read.

Regarding the opposing CSS variables point, I want to add that people can always configure Tailwind to use var(...) as color value, for example:

module.exports = {
  theme: {
    colors: {
      purple: "var(--color-purple)"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

So it's a non-issue.

Collapse
 
ryanhiebert profile image
Ryan Hiebert

How would you relate it to CUBE CSS?

Collapse
 
swyx profile image
swyx

no idea. you take a crack at it?

Collapse
 
ryanhiebert profile image
Ryan Hiebert

I really like what I've seen from the philosophy behind CUBE CSS piccalil.li/blog/cube-css/. From what I can gather (and I don't trust my assessment, so recognize that these are unpolished musings), it seems to me that tailwind, which would fit into the "U" of CUBE, should fall behind the compositional CSS that CUBE CSS recommends as a first step.

This makes sense to me. You've pointed out some really good reasons why CSS-in-JS and module systems have challenges. I'm inclined to think that there's still a proper place for using CSS cascade as it is designed, even while using utility classes.

Thread Thread
 
swyx profile image
swyx

i took a quick look. i'd say you're being too superficial if you shoehorn tailwind into "U". the ultimate philosophy tailwind espouses is way more extreme - devolve all components into their most atomic elements and never bother with creating any classes or exceptions or composition selectors. this suits a much more fluid development style. i agree there is still a proper place for the cascade but it is likely <5% of the styles you write rather than 50% (for illustrative purposes just talkign about order of magnitude)

Thread Thread
 
ryanhiebert profile image
Ryan Hiebert

Thanks, I appreciate your thoughts on it. I don't have enough experience writing CSS to give the kind of evaluation that you just did, so that's very helpful.

Collapse
 
j08438911 profile image
J

You can use the .cls button in chrome to design in browser with autocomplete and toggle buttons to turn classes on and off like this: twitter.com/calebporzio/status/102...

Collapse
 
swyx profile image
swyx • Edited

update: this is a normal part of my Tailwind workflow now, thank you for teaching me this :)

Collapse
 
swyx profile image
swyx

ah, cool, I did see that in someone's livestream!

Collapse
 
tomhermans profile image
tom hermans

Just how I think about it. Clear consistent future-proof naming, defined logic, easy to remove without breaking and transportable to future projects.

 
swyx profile image
swyx

this is why I don't bother engaging in perf debates without a benchmark haha.

Collapse
 
beyondervn profile image
ngo hoang long

because it never goes wrong

Collapse
 
titungdup profile image
dhondup

"Utility-First, not Utility-Only" sounds good on paper but after using it for a while you will go Utility-Only unless you have some rules to keep those in check.

Collapse
 
andthensumm profile image
Matt Marks 🐣

That style-x though....

That is exactly what I want for cross platform web and mobile

Collapse
 
swyx profile image
swyx • Edited

btw i tried to illustrate these tradeoffs but failed horribly - pls feel free to take this and do something better excalidraw.com/#json=5756456242511...