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...
For further actions, you may consider blocking this person and/or reporting abuse
@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.
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.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.
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.
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...
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.
Tailwind is just CSS-in-HTML though...
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.
you always have my permission, just do it :)
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.
thank you! will update
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 :)
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.
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.
@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.
nothing in perf is simple. how do you account for gzip of your html?
True gzip might be compressing and mitigating for all the repetition
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.
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?"
Oh that BEM argument hits too close
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.
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?
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.
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...
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.
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" >
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:So it's a non-issue.
How would you relate it to CUBE CSS?
no idea. you take a crack at it?
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.
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)
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.
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...
update: this is a normal part of my Tailwind workflow now, thank you for teaching me this :)
ah, cool, I did see that in someone's livestream!
Just how I think about it. Clear consistent future-proof naming, defined logic, easy to remove without breaking and transportable to future projects.
this is why I don't bother engaging in perf debates without a benchmark haha.
because it never goes wrong
"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.
That style-x though....
That is exactly what I want for cross platform web and mobile
btw i tried to illustrate these tradeoffs but failed horribly - pls feel free to take this and do something better excalidraw.com/#json=5756456242511...