Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Why I Love Tailwind (mxstbr.com)
266 points by 0xedb on Dec 7, 2020 | hide | past | favorite | 288 comments


That example also encapsulates everything that wrong with how CSS is used today.

The markup contains no information about what the contents are anymore, so you lose the ability to target anything that is X: for example an email, an avatar within a 'people-card' etc.

HTML/CSS was supposed to separate content from looks. Of course that ship has sailed long ago, since modern day development seems to be insistent and mushing HTML, CSS and JS together in the same file. Looks is logic is content is looks is a mess.

HTML/CSS was also supposed to be re-usable. Now instead the re-usability is within react/angular/etc. components, so you now have to use react and javascript everywhere you want to show similar elements - if you want to have the ability to easily change them later.

Of course this isn't the point. If you have the ability to work with react components, you probably are knowledgeable enough to use CSS.

So the only remaining use-case is "way for non-technical people to write objectively bad HTML and have it look nice".

Which again, is fine. Sometimes bad is good enough when the alternative is nothing at all.

I'm still not a fan.


Check out the Tailwind author's reasoning: https://adamwathan.me/css-utility-classes-and-separation-of-...

I find it more compelling than I expected.

The truth of the matter is that as much as the idea of separation of html vs css sounds good, it's so hard that I rarely see it done. Without constant vigilance, you end up with premature abstractions, things you can't actually reuse, and an append-only accumulation of CSS.

The dream sounds good but leaves all the hard details for you to work out yourself. And frankly, after over a decade, I remain unconvinced and ready to look for new ideas.

Breaking the rule with Bootstrap since it first came out never stopped me from building great things, yet trying to obey the rule slowed me down and had me constantly refactoring CSS. It feels like a cargo cult.

We've been pointing to CSS Zen Garden for 17 years as an example of the benefits, but giving everything a class so that you can address it from a .css file isn't the hard part, and that's all the garden shows. The hard parts are organization, maintenance, coming up with a unified strategy, playing CSS whack-a-mole when you change HTML, deciding where to define what, finding where you defined what, etc. The garden demonstrates none of that.


The hard parts are organization, maintenance, coming up with a unified strategy, playing CSS whack-a-mole when you change HTML, deciding where to define what, finding where you defined what, etc. The garden demonstrates none of that.

100% this.

The moment I started to see HTML and CSS as a holistic system of layout construction, rather than as simply two separate but complimentary technologies, my productivity in both skyrocketed.

'Bugs' in my CSS became infinitely easier to not only find, but also solve. And the benefits of tools that both unified and abstracted layout construction, like Tailwind, became immediately obvious.

Shameless plug: I talk more about a lot of these mindset shifts and how they've helped me finally feel like I truly understand CSS in a book I'm working on called "How To Debug CSS" [1].

It goes over not only the mindset shifts that have helped me gain a decent level of mastery over CSS, but also shows you how to solve the 50+ most common issues that you'll come across when developing with it. Like when you have an overflow on your page for example, and have no idea what's causing it.

[1] - https://gumroad.com/l/Debbg/z823cp8


I don’t personally mind the plug, but please give something concrete to help us understand what you mean when you say “holistic system of layout construction” and others.


Happy to expand.

One of the concepts I share in the book is on the idea of viewing HTML as a relational structure. Like a database. And how viewing it in that way helps you to better understand positioning (even with CSS). Because re-framing it in this way automatically gets you thinking about your elements, and the CSS that binds them, more holistically.

The most common way that people trip themselves up when working with HTML and CSS is by becoming myopic with regard to the specific section or element they're dealing with, and not seeing the whole forest so to speak. Making them unable to see why a problem in their CSS is happening.

Or to know what they need to do to create a certain thing in their layout.

A lack of a holistic understanding (how elements relate to other elements, and how CSS fits into this), and thereby view is what causes this.

My two latest articles goes into more detail re this:

https://planflow.dev/blog/how-to-get-better-at-css

https://planflow.dev/blog/what-makes-css-hard-to-debug


I hope you understand when I say that your reply still does not contain anything concrete. Nor for the most part do the articles you posted.

I put some significant time trying to understand exactly what you’re going for and it seems like you’re trying to help people shift their high-level thinking, but it’s a lot of words and almost nothing to get my hands on. As someone who needs to try and work with things in order to properly understand them, this material just does not give me any “meat”.


I appreciate the feedback. The reason why it feels like this is because I haven't included any real CSS based examples here (which I do in the book) of what I mean.

These are not easy concepts to digest without visual examples. I will try to edit my posts with some concrete examples to get them to be closer to the book.


Awesome. If/when you do, try to reply here as I’m genuinely curious.


I didn't follow what was wrong with his Option 2 solution. A hybrid approach between that and Option 3, where you define a "base class" like he does in Option 3, but don't use it directly in the HTML, instead use @extend or @mixin to reuse it for the semantic classes that are styled similarly seems like the best of both worlds. A core "style library" like CSS, but you apply to semantic chunks in CSS instead of in the HTML.


That's actually the recommended way to componentize Tailwind using @apply once the styles grow too large and repetitive (no naming convention guidelines as far as I know, though). They got a big improvement in version 2 since now you can @apply styles with media rules and state modifiers like hover.

Tailwind is the first coherent CSS framework that makes that mixin design pattern work in my experience. Before, such designs usually drifted towards a spaghetti meta layer over regular CSS, creating an exponential mess. The added benefit of being able to go inline utility classes -> class names only when you want to (like when you've got a better view of the big picture) should not be underestimated.


I think the main advantage of Tailwind is actually the fact it's a preset design system, rather than it being utility first.

If you defined a design system upfront you could do practically the same thing that Tailwind does except at a component level. On the flip side, it seems like even in Tailwind it seems like there are opportunities to create a mess.

I'm not a fan of the utility level of abstraction Tailwind is at, but I see the value. It seems wrong to view Tailwind as a CSS solution though, since in my opinion it's actually a design system solution.


> The truth of the matter is that as much as the idea of separation of html vs css sounds good

So why not just use <center> and <font>? That was my immediate thought the first time I saw Tailwind HTML: it's the HTML1 tags, but they are now attribute values.


...because they don't compose as well?

But you are correct. The idea of functional css libraries is to go back to putting presentational information in the html. And the justification is that it is a better approach when you are building a webapp with a component library.


for one thing, they are not responsive.


I read that article and it appears that his arguments for developing this framework boil down to: "what if you could create inconsistently designed pages easily?"

That's a footgun if I've ever seen one.


Tailwinds also acts a design system for your site, you have a set of paddings, margins, colors, font sizes, breakpoints, etc that make up your design system.

In my experience it results in more consistent designs because everything must come from what you make available in your tailwinds config.


The real problem is that tools like this appeal to people who dislike or not willing to learn or to do anything with CSS. And if we accept that tools are written by the authors to save their own problems, then we get what the tools like this are written by people who do not understand/like/whatever CSS. And the cycle continues.


That's just dismissing all of us who like Tailwind /and/ have a decade+ of experience doing all of this 'the right way' without bothering to properly argue. It's a very cheap comment.

(but not out of line with your general conduct here, I suppose. I often wonder what people such as yourself get out of it...)


What do you get out of ad hominem? You are the answer why people such as myself do not "properly argue".


Lol.


> HTML/CSS was supposed to separate content from looks. Of course that ship has sailed long ago, since modern day development seems to be insistent and mushing HTML, CSS and JS together in the same file.

As a developer, what incentive do I have to scrupulously maintain the separation between content and appearance? Users do not appear to demand it, and customers or employers will not demand it either - they might care if the users hassled them about it, but this does not happen.

> HTML/CSS was also supposed to be re-usable. Now instead the re-usability is within react/angular/etc. components, so you now have to use react and javascript everywhere you want to show similar elements - if you want to have the ability to easily change them later.

If HTML/CSS was supposed to be re-usable, then it might have been a good idea to have designed those languages to support the kinds of re-use that are actually needed. One of the useful features of Tailwind, for instance, is that it becomes possible to copy HTML from one page to another while preserving consistent appearance, because all of the information necessary to display the element is contained within the class names. With most CSS, this is not the case: styles will depend on complex selectors, such that an element may appear completely differently depending on its ancestor elements.

The brittleness of CSS leads to various hacks and abstractions, and it is these hacks and abstractions that make re-use difficult. In reality, CSS depends on the structure of the HTML to work properly, and HTML has to be structured to suit the needs of CSS. This makes it hard to write general-purpose CSS that can effectively re-skin a HTML page, and to write HTML that is easy to lay out in the desired manner with pure CSS. It just doesn't work well enough to make the dream of decoupled content/styling workable in enough cases.


If you write using random style tags everywhere the next time you want to change all h1s you have to go file by file.

Some people say sure but when are you ever going to change a style? Surprisely more often than hunting every h1


That is what components are for.

Nobody is writing "random" styles, we just found that selfs sufficient components are more reusable than something that's split out across technologies.


It works fine and have worked for 15+ years.


> HTML/CSS was supposed to separate content from looks.

IMO the problem is that HTML is woefully inadequate for expressing the sort of content we have today on the web.

It’s a document container that we’ve shoe-horned an application platform into. Much of what is displayed on some of the most popular sites can’t even be described as “content”—it’s interface, and that’s where things fall down.

It’s hard to follow semantics when the only option you have is positioning and styling divs. In that regard the style becomes part of the content. Nested divs have no meaning, and there’s no way to give them meaning in the same way that <p> is a paragraph. Aria labels help on the accessibility front, but outside of that the only way to express meaning of something like a modal or a popover is visually.


> Nested divs have no meaning

That's pretty much true now[1], but the original meaning of "div" was "document division"[2] — i.e. they were similar to the current "section" element.

> outside of that the only way to express meaning of something like a modal or a popover is visually.

That is (was?) the point of 'semantic' CSS and the separation of concerns. A div is (now) just a generic block, but a div with an id or a classname means something dammit.

1. https://html.spec.whatwg.org/#the-div-element

2. https://www.w3.org/TR/2018/SPSD-html32-20180315/#div


You don't have to use React and JS to get components. You can still get components with server or build time rendered HTML. About the only time you can't is if you are writing html and css files by hand. If you have some kind of css preprocessing going on, you can still get there with Tailwind's @apply with hand written html.

Whether components are a good thing in this particular context is debatable. But you can create them without JS.


What templating library do you use that provides components? And no, partials are not a substitution.


You can do server-side JSX I believe. Almost all front-end frameworks (eg Vue, Svelte, Riot) support SSR but you have to use JS on the server. Why PHP/Python haven't caught on and reworked their template syntax to look like nestable tag components with props is beyond me. Maybe an idea for a new open-source lib, JSX for PHP?


Why aren't partials a substitution in the context of Tailwind? The only goal is to keep classes DRY.


Stencil to build WebComponents ?


> If you have the ability to work with react components, you probably are knowledgeable enough to use CSS.

If you are building a webapp, nobody is knowledgeable enough to use css because css is broken for this use case. Tailwindcss is absolutely aimed at css experts. There is nothing for non-technical people in tailwindcss because it exposes all the existing css properties, just with a selection of values.


and that's a big reason for why I love it! I'm so tired of seeing a bunch of divs being added to components just to get them aligned to the page's main grid. Give me a couple of classes for applying gutter width and as either padding/margin/gap and I'll apply it as actually needed!


Please excuse if my questions seem rude, but I'm very curious:

1. How many UIs for websites / webapps have you written by yourself?

2. How many while working within a team?

I have a modest web UI dev experience myself and Tailwind doesn't seem that crazy to me. I've tried the techniques you seem to be advocating, but the idea of them sounded better than they actually were in practice.


The way I see it, some commenters here keep holding on to their 'html is content, css is styling' mantra because, well, all of us old-schoolers have held to that for a long time.

Some of us realized it never really works in practice, and never really made sense in the first place (as many here and in the past have argued). Others decide to hold on to the mantra and feel a need to be arrogant or dismissive to those they disagree with.

I respect fellow front-enders who are happy doing things their way. Not everyone needs Tailwind. But it's frustrating to and honestly somewhat baffling to see a bunch of them dig their heels in the sand and defend their approach by assuming all the rest of us just "don't know CSS". It's a minority, but a vocal one.


When you are asking questions like those on HN of all places there's a decent risk you picked the wrong hill to die on.

Avoid trying to get into a situation where people are just quoting their credentials at each other, playing a game of who will run out things to list first, being none the wiser once they're finally done a decade from now.

In case it wasn't meant the way I believe your comment was meant, you probably still shouldn't judge my comment by whatever I did in the past. If my personal experience was somehow relevant, I would have included references.


It was an honest question. I didn't try to "quote my credentials" or claim that I'm a frontend expert. If anything I meant to say that my frontend experience is limited.

My point was that: in this case the experience might be relevant, because the ideals of traditional HTML/CSS sound good, but don't turn out as great in practice.


If you're working on the content and the looks at the same time, and you don't 100% know where the project is going, it's helpful to consider them as a combined unit, so you can alter and/or discard that unit without delving into separate CSS and HTML trees. (Or, worse, not being sure what HTML or CSS you should alter or throw away when its corresponding CSS or HTML ends up in the garbage).

Separate content and presentation is a great final outcome, but when a project is in flux as it's being built, it's a burden.

EDIT: Moreover, it's not just that the "ship has sailed long ago"; the ship was attacked and sunk. Frameworks that combine CSS and HTML aren't doing so out of neglect; they're aggressively rejecting the separate looks/content paradigm.


I'm not a fan either. The always cited rationale does not click with me, it even pushes me more away from the concept.

For me it tells in short: "Well, you could have nice and clean semantic CSS if you created and followed a design doc. Use tailwind and cryptic classes that could be whatever in any other project, if you don't bother about design docs."

I believe things like tailwind make developers less knowledgable of their craft. This has a big advantage though - you can have more people doing code for you, they don't need to know CSS at all to some extent.


Having used it for the better part of a year, I can tell you that using Tailwind has vastly improved my CSS. Now, I'm basically using CSS all the time, with the ability to do media queries quickly; so I guess my thoughts are the exact opposite- it helps you learn CSS even better than you ever would have.

Extracting out components and using @apply when I desire is fast and easy too.


+1 from me. When I started as the sole (junior) Dev at work I wasn't very good with css. I made use of things like bootstrap etc heavily. Eventually I found tailwind and started using that to augment what I was building, and now I use it solely.Thanks to tailwind I have a much better understanding of css.


there is nothing stopping you from using @apply in custom classes if you really want to - or using data attributes for targeting, depending on your use case.


Frameworks like Tailwind CSS will go the way of the dodo, once CSS gets proper scoping, isolation and inheritance. (No JS needed). Then you can truly have semantic HTML with presentational stuff separated cleanly without needing any toolchain or 1k+ deps library to do this.


Ok that sounds fantastic, how long should we wait until that's the case and is adopted by all browsers and is backward compatible? That's the issue here.


Ballpark guess - less than 5 years. There is the work ongoing on CSS and HTM modules at:

https://github.com/WICG/webcomponents/blob/gh-pages/proposal...

https://github.com/WICG/webcomponents/blob/gh-pages/proposal...


Scoping is one part of the problem. Complex selector is another one. Design consistency is yet another one.

Tailwindcss is solving those 3 issues.


When is that going to happen?


One of the reasons I moved away from web presentation projects is overwhelming frustration at just this: There is no other area of technology where there is so much running to stand still: Massive amounts of make-work and "innovation" to do pretty much exactly what people did in 1999. It is extraordinary how many libraries and magical solutions can be embedded to create something that a 15 year old in Notepad threw together with basic CSS and HMTL twenty years ago.

I apologize to the web community at large for the snarky, dismissive tone, but seriously it just seems extraordinary how it's just an endless march of new approaches and new silver bullets to do absolutely trivial things. Arguments about maintainability or extensibility fall by the wayside when that trend du jour is discarded next month because now it's being rebuilt on Backwind on the Spry framework using the TypelessScript stack, etc.

I am absolutely in awe at the advancement in virtually every other area of technology, almost all of it worth every bit of attention and learning. Where we are building enormous, hugely complex projects. Then we have the web where after countless "toss it all and throw it all away" cycles, the community is heralding this. This is what has, to quote the linked article, " taken the frontend world by storm".


I have no idea about Tailwind and have never used it. That being said, your apprehension at making this statement is valid. To call it "absolutely trivial" is absurdly dismissive. Just because you don't think design and layout are important or difficult does not make it so. I know several designers that would take serious offense to you comparing their work to that of a 15 year old's throwaway.

Visualization and UI design are a maturing field, and the constant iteration on HTML and CSS is to support the designer's ability to take their vision and realize it on the page.


"Just because you don't think design and layout are not important or difficult"

I said neither of these and am not interested in debating a strawman.


I'm not sure why your dismissive tone is somehow upvoted here. I rarely comment and do not see how this as a strawman. If this is not a strawman, then explain how a 15yo with notepad can do the same as these solutions with a defensible stance. Is it because the person replying to you wasn't nice and give you fluffy kind words? I'm not understanding why the thin skin here. If you make a bold statement, it should be able to be backed up. Problem is here that you can't, so just ad hominem instead.


You pulled this account out -- one that had been untouched for seemingly seven years -- to make these insults?

If you can't separate design from Yet Another Trivial Variation on a Theme, that's a you problem. Trying to conflate the two is disingenuous.


Yep, 7 years. Reflective of the quality of conversation here, where I read daily but don't interact. However, seeing quality lower even further by baseless well-written opinions prompted me to respond. I'm especially disappointed to see when someone challenges an opinion that it got downvoted. This type of voting behavior makes having a dialog impossible. I'm not even saying you're wrong here, just the reaction is lacking substance.


I stated a general sentiment of the trends in web development, where there is an extraordinary amount of work to effectively reinvent the wheel, and then to uninvent the wheel and herald why using a cube is superior, until eventually you herald the wheel again. It's bizarre.

The work product of teams chasing each of these innovations is virtually unchanged, decade over decade. Which is exactly why you see a circular procession of revolutions, each displacing the last to the dustbin of history, while empirically offering nothing unique.

Clearly there are a lot of people that empathize with it. There is nothing "baseless" about that, however uncomfortable some find it.

Bizarre that you claimed that my comment was an "ad hominem", when your own reply included multiple personal attacks and mine included none. They (you?) literally tried to discount my comment by contriving a strawman that if this application and management of CSS is trivial, therefore I'm saying that design is trivial. That is absurd, and is completely orthogonal.


What exactly do you think all these libraries and magical solutions are trying to address then? 15 year olds putting a spinning link gif on a static HTML page?


In fairness those pages offered more content per square inch than modern whitespace centric design.


They try do address the fear of dealing with CSS by people who do not know nor want to know it.


Your entire criticism boils down to "what waste of time trying to solve trivial things" without defining what you regard as trivial.


It doesn't, but you are welcome to enjoy your own bias in your interpretation.


If it doesn't, surely, you can define what you mean by "trivial things"?


[flagged]


Twenty years ago I was the lead architect of a web application -- I'm 48 now, for the ageists who would like to dismiss based upon that -- that was a power generation monitoring and control panel for distributed power across the US. We were one of the first users in the world of the XMLHttpRequest ActiveX object that the MSXML team released through subterfuge (I know because we hit every defect head first).

Since then I directed development on a number of absurdly rich and powerful platforms across telecom and the financial world. We were leading the respective industries when everyone was pushing Java, Flash, XAML/WinForms, etc at various junctures (each coming and faltering). We had a better than native mobile "app" using web tech.

I was one of the early and vigorous public proponents of SVG.

These applications, going back up to two decades ago, demolish the overwhelming bulk of web apps people are working on today in design complexity, actual functionality, and so on.

Yeah, I have a pretty good notion about "modern web technology", and often it feels like farce. Like it's a parody and I'm left wondering if I should say something because I missed the joke. The amazing self-congratulatory praise about, again, trivial nonsense just boggles.


[flagged]


Yeah, something like that...

Or, and maybe this is just my old man dementia talking, millions of extremely low-skill developers have flooded into the market, primarily building "web apps". An endless procession of "make trivial stuff easy for really incompetent developers" solutions appear to pander to them -- and their brother-in-arms "make trivial stuff seem complex and engineer-ee" solutions -- and this is a group that finds each of these variations on an obsolete theme revolutionary.

Humorous that multiple people have been triggered by the notepad comment. Yet...many extremely rich pages and apps have been built in exactly such a manner! That this is seen as outlandish is pretty telling.


I get where you’re coming from, having lived through much of what you have myself. The linked article here is not actually that interesting, and arguably ruins the image of Tailwind a little.

After dealing with a sea of generally pretty junk libraries and patterns for a while now, I know what I like and what I think works well.

Tailwind is nice. It provides utility css classes to help you write css faster. Trying to do responsive work in regular css is a pita with media queries - tailwind improves on that dramatically. It’s proper regular css, just like you know and love. With a bunch of classes that let you a) tidy things up so the design is a bit more honoured b) give you utilities for common patterns and c) allow you to be more expressive without having to reach for more clumsy css nesting. It’s just css. Old school css. You can give classes your own names like you always did before.

If anything, tailwind is the pendulum swinging back to how things used to be. It’s just being misrepresented here.


The fact that you are so trivially dismissing all of the complexities of the web leads me to believe you in fact have very little actual experience. If you are half as experienced as you say you would have more substance to back up your claims. Maybe start a blog and share your god like experience and wisdom with all of us plebs.


I might be wrong of course, but I understand what bfgoodrich is saying as follows:

Back in the day, before we had all the build pipeline, npm, utility-first, etc css people were already building websites and those also worked just fine.

I sort of agree. There was very little you couldn't do that was a result of the tools to build the sites. The only real constraints were imposed by what technologies were in the standards and which were implemented by browsers.

If you want to build a website today with what is 'normal' tech, you have to learn a whole lot more and people spend tremendous amounts of time in bootstrapping code in order to produce some JavaScript and CSS that in the end provides hardly any added value compared to server-side rendered views with sprinkles of JavaScript.

Apps like Slack are probably an exception to the server-side rendered argument, but I think you'd be better off building those in non-web technology to begin with.

Either way, if you want to spend your days building layers upon layers of abstractions in order to prevent having to fetch some HTML from the server, be my guest.


"Complexities of the web" are all self-inflicted. First, by thinking that everything on the web should be an app. Second, 99% of the complexities is tooling. Downloading two megabytes of crap just to show half a kilobyte of texts is pure madness, yet somehow acceptable, because "complexities".


There is enormous complexity in the field. But, and this is a big but, 99% of the advocacy and "innovation" is in the easiest, most trivial 5% (rough numbers). That I'm pointing out how absurdly circular this is in no universe denigrates the entire realm. But of course it makes criticism easier to pretend it is.

I had no idea my comment would make so many so insecure.


No need for insults or calling people insecure when all I asked for is examples/substance to back your claims. Let's see some screenshots of these cutting edge applications developed 15 years ago. I'd love to see how you made them rich, interactive, and work across a wide variety of devices (mobile, tablets, workstations) with varying screen densities. I'd also be curious how performant these applications were, how much data was being conveyed on screen, etc... Maybe a blog post detailing the architecture and how you achieve all of the concerns of the modern web using bare JS from 15 years ago.


You sound like someone who is at the beginning of the learning curve. Nothing wrong with that but don't be so hostile.

People used tables for positioning and as containers. More data was present compared to whitespace and mobile reduced sites.

People had different screensizes back than. How do you deal with that? You take a 3x3 cell. You cut a picture into 9 slices. You take the top, left, right and bottom images and make them a background at 100% width (top/bottom) or height.

That is the basics of a simple flexibile container.


The discussions of Tailwind are always heated but fundamentally boring because all the threads are started by people making the obvious objections that arise before you use it which were answered by Adam three years ago.[1] Do people who have actually used Tailwind in a real project have anything to add?

[1] https://adamwathan.me/css-utility-classes-and-separation-of-...

For my part, I am seeing slow rendering on some of my sites (page doesn't appear on webpagetest.org until 1s after network is done), and I wonder if maybe having atomic CSS is slower to render? Anyone have experience with that?


This is a completely ridiculous argument. You're essentially saying that anyone who has objections to a particular tool has never used it, for if they had, they'd certainly love it.

Well I've written Tailwind extensively and I don't care for it at all. I also don't agree with most of Adam's arguments, whether made three years ago or today. Shocking, apparently!


No, I’m saying that discussion of TW on HN is dominated by points that aren’t relevant if you’ve used it. There are plenty of real ways to criticize TW—the choice of variants is quirky, dev builds slow hot reloading a lot, it doesn’t cover a lot of cases which leads to “Bailwind”, and more I’m sure that I’m not thinking of now—but the criticisms that “it adds too many classes to HTML” or “semantics!” are boring and not useful.


I suspect you're trolling because your other comment implies that you don't know Tailwind at all.


I've written thousands of lines of React components and stylesheets using Tailwind. Have you?


It’s literally the No True Scotsman fallacy


Most replies are having their Green Eggs and Ham moment.

I do not like green eggs and ham. I do not like them, Sam I am.

Meanwhile, people who have actually used it, find it great. It's a wonderful framework.


I find that both tastes are awful. The problems Wathan points out in that blog post are real, but the solution he came up with is a different kind of awful.


> Anyone have experience with that?

Similar issue for me. I wanted to try Tailwind on my current project and started by including their CSS on my site which made it sluggishly slow (Firefox on Mac). It was in dev mode so no tree shaking but I was too bothered by this new slowness (e.g. select menues taking 1s to open) so I stopped that experiment.


Have you profiled your page? I have used it on medium project and I haven't had any painting speed issue.


I can't figure out how to get Chrome to tell me what element is making initial render slow. There are a lot of tutorials for figuring out why JS re-rendering is slow once you have a layout, but there doesn't seem to be a way to identify problems with initial render that I have found.


Can you start by completely blocking the css to check if that’s definitely the issue?

I’d quite like to know if there’s a genuine issue to be concerned about.


Here is the site with the media=print hack:

https://www.webpagetest.org/result/201207_DiW4_9712575effac2...

You can see it displays the no CSS version around 900ms and then it takes until 1900ms to display the CSS version.


Curious. It renders fast when I hit it on mobile.


Same here – very fast on mobile Safari.


I suspect there’s something going on where webpagetest has an unrealistically slow CPU render time.


I'm assuming there's something going on between the flash of the heart and the app render that's causing the slowness.

By profiling in Chrome (Performance tab -> refresh) it looks like the animations are causing the issue. Having said that, as a user it feels reasonably fast and it's just the flashing content that's weird.


Well, I don't like Tailwind and I admit that haven't use it. I browsed a lot about it and read the rationale twice already (it's looks amazing how often this article has been cited in just this thread). And I got more away from it after first read, and even more opposed to it after the second read.

I maintain projects, across multiple stacks, and Tailwind just looks like it would be a nightmare to maintain in the projects I work and worked. I've played a lot with the https://play.tailwindcss.com/ and my objections are even greater. Repetition of classes would cause much more painful style changes. Debugging in chrome looks like a struggle. Cryptic class names that might be used by many other libs or even might be meaning completely different things in other than the current project, renders codebase modularity as not possible - if I want to take something and then show it somewhere else outside my project, I will have hunt for WTH is overriding my styles, just to figure out that one of the "py-8 text-base leading-6 space-y-4 text-gray-700 sm:text-lg sm:leading-7" (instead of "content-container"), means something else on target site and simple name spacing encapsulation does not work fully. The example page does not even semantic use HTML tags - which to me tells that "semantic" might be completely misunderstood by the lib author.

Simple design doc in the project would solve problems raised in the said rationale. Indeed - Tailwind seems to be a ready-to-eat design doc. The problem is that it is the same design doc for all people using it.

Those reasons makes me not even remotely tempted to try Tailwind.


Your objection seems to be: I can't move a component from a TW project to a non-TW project, and it would be difficult to combine a TW project and non-TW project. Is that a fair summary?

On the first point, moving a component from one project to another one that use a different CSS framework is sort of a weird thing to do. I've seen cases where people combine Bootstrap with a bunch of random personal styles, but I haven't seen anyone combine Bootstrap with e.g. Material design. ISTM if you're combining projects, you'll get a lot of CSS bloat and unexpected interactions.

On point two, you actually can tell TW to use a prefix, so instead of margin-left/right: auto being "mx-auto" it would be "prefix-mx-auto". Doing that would let you combine TW with another project that used the same class names (though obviously, you're going to have to go back and fix all the class names in an existing component).

TW's niche, ISTM, is for people who want to make small-ish, highly customized sites quickly. I don't you'll be happy with it if you need to integrate with a lot of legacy CSS. I also think if you don't really need custom styles, then you can just use Bootstrap/Material/Bulma/whatever and it will be much simpler than having to make all your buttons yourself or whatever. But for things like isolated landing pages, TW is great because you get an experience that is like writing a new CSS file, but quicker (no need to switch between the HTML and CSS or make up names) and better guided (preset variables for the sizes, colors, and breakpoints).


Wasn't the whole point of CSS to separate presentation from data, and move away from <font color=red> and other <table> that made layouts too difficult to change? Consider this:

<h2 class="text-purple-500">Customer Support</h2>

How is this different from <h2><font color="purple">Customer Support</font></h2>? This is still considered bad practice, right?


From the tailwind homepage:

> "Best practices" don't actually work. I’ve written a few thousand words [0] 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.

[0] https://adamwathan.me/css-utility-classes-and-separation-of-...

FWIW, that linked post was the thing that convinced me to try it, and I haven't looked back.


As another example of "am I crazy? No, it's the entire rest of the internet that's crazy" check out htmx [0]. It's another acknowledgement that best practices (for js / ajax) are not best in all circumstances, and has been a fantastic fit for most of my web projects.

In practice, "the right way" is shorthand for "the right way for your project", and conventional wisdom / best practices are vital to know and understand so that you can recognize when they are a bad fit for what you need to do.

[0] https://htmx.org/


I was going to mention how similar this is to intercooler then I saw:

> htmx is the successor to intercooler.js


still, this does not explain, why I should use

class="w-24"

instead of

style="width:24px;"

Other than "inline style bad", when the first one is built into the browser, and a second one requires including an external dependency, that I imagine contains classes w-1 to w-1000 or whatever. Now I strain my IDE-s autocomplete with 1000s of classes, will need a css minifier/bundler (that will at least make my build slower). I'm not a frontend dev, but I do dabble in writing the occasional website, and other than bootstrap (which contains complete styles for stuff like buttons), I never felt the need to use a CSS framework. I get it that in pre-grid days, it was a minor feat of wizardry to implement complex layouts, but nowadays, frameworks seem largely unnecessary to me. Another added benefit of using pure CSS, is you just have to learn it once (with tons of great resources), while with these CSS frameworks, I'll need to learn what everything's called for every framework.

Not sold.


CSS classes can work with media queries while inline styles cannot. A ton of the classes that are generated are screen size variants.

The IDE strain is overblown. There is an official Tailwind plugin for most IDEs and it performs well, even with the massive CSS files you use for development (but are purged/tree-shaken for production). Computers are really good at parsing text, and even at their worst, the CSS files are never more than a MB or two. Even if you enable ever single flag for every token, the dev file size is around 10MB I think. Big to load over the internet, but locally, and being parsed, not a huge problem at all.


There's a section of Wathan's article, "Isn't this just inline styles?" That directly addresses this question. Perhaps you missed it?

> With inline styles, there are no constraints on what values you choose. [With utility classes] you can't just pick any value want; you have to choose from a curated list.


If the list is so long that the whole thing isn't even included by default and you need to custom configure which entries appear on the list, it's not that much better than arbitrary values.


Here's why, media queries:

class="w-24 sm:w-36 md:w-48"

Now I have a nicely designed interface for multiple sizes and it just works.


except that w-24 is not 24px. It's 24 units of whatever your design grid says, so now you can use a design language to describe your layouts instead of absolute dimensions


And for more information on why "24" there isn't just an arbitrary magic number like it was in the original inline style: https://styled-system.com/guides/why-powers-of-two/


Other people have noted that your `style` example isn't responsive, but on top of that, there's nothing stopping you (or a collaborator) from writing `style="width:26px;"` somewhere else in the app. Having a restricted set of options helps enforce consistency across a project and gives you a much nicer look by default. This is especially useful for devs doing frontend work without a strong design background.


This post may clear things up a bit (disclaimer, I wrote it):

"Utility classes vs. inline styles": https://critter.blog/2018/05/04/utility-classes-vs-inline-st...


Nice article. It manages to explain the uneasy feeling I've always had when people authoritatively talk about "decoupling HTML and CSS". The coupling is somewhere, and where it is causes tradeoffs that need to be considered.


Semantic CSS would be great if you could reliably unit-test style changes to semantic names within the IDE.


> "Best practices" don't actually work.

Don't try and master the hard stuff: you'll just fail! Take my magic pill!

Applied to everything from weight-loss to front-end development.


Maybe it was never as good of an idea as people thought?

'Best practises' is a terrible name, as there's no absolute idea of 'best' anyway. It's all just someone's opinion.


Most innovative ideas at first seem like bad ideas. Flipping conventional wisdom on its head takes a while.

This talk by Dan Abramov helped me understand better how 'best practices' are often taken so literally that their value is lost: https://www.deconstructconf.com/2019/dan-abramov-the-wet-cod...


I agree with you, Dan, and Adam Wathan for that matter.

The point of my comment had more to do with front-loading of a pitch with copy specifically tailored for confirmation bias.

Running to achieve weight loss can be hard. So much so that it's intended value can't be realized, or even be detrimental to the end goal. But I think we'd agree that anyone who simply says says "Running won't help you lose weight because it doesn't work, try this instead" is not seeking to help you, just sell you.


This was also React's initial pitch as well: getting DOM updates right is hard, use vDom instead!

The truth is that the majority of frontend development is devs racing to shovle the latest stack of tickets that management cooked up with little collaboration or rhyme and reason into the Done column of JIRA (web dev is particularly imperiled by shitty lay management), any DX affordance they can get their hands on is valuable to this goal

Concurrently, designers are pumping out comps as fast as possible to match pace with no real system cohering the whole thing, you need a design system to provide an "abstract interface", so to speak, for your CSS to really transcend into real separation.

This is just what I've observed working at my comp


Come one. This "pitch" is heavily contextualized. Interpreting it as "all best practices are bad" is not very charitable.


I guess that's falling into the same trap people fell into when they rejected React because the html was wired directly to JS. There's now component level isolation that means you're not working at a global level anymore, and you can reuse those components.

The issue with CSS has always been that you create these lovely generic styles, and as time goes on it becomes harder to make changes without breaking other components. Despite good intentions and large amounts of effort, things become coupled.

The issue with your example above is that it doesn't handle all the cases. You can't deal with responsive layouts or hover states etc.

Tailwind addresses these 2 issues. They reject global stylesheets by working at the component level. You can change a component knowing that you won't break anything else. By using classes, you get to have all the substates configured locally without having to use global stylesheets.

A lot of what's happening in the CSS world now is about ditching the global cascading nature of CSS and trying to isolate styles. Like it or not, that's the direction it's moving, for very good reasons. All the CSS-in-JS solutions have tried to do it too, but honestly, for me, the dev experience sucks.

Tailwind gives me css back and it's fun again.


> Wasn't the whole point of CSS to separate presentation from data

Well, no, not really. It was intended to stem the tide of HTML devolving entirely into a presentation language, but H.W.Lie's thesis[1] makes it quite clear that HTML was always expected to remain a middle ground mish-mash of structure, content, and presentation, one in which everyday authors could still intuitively grasp the purpose of standard elements, and over which CSS would then supply some contextual visual order.

The fundamental notion of CSS is a rich and versatile and non-Turing-complete set of overlaying structural selectors, a design somewhat in reaction to the perceived inapproachability and abstraction of DSSSL; something that still pains me even two decades after that battle was lost.

[1] https://www.wiumlie.no/2006/phd/css.pdf


In my experience it has a lot to do with the scale of the project. Beyond a certain size (lines of code, length of time, number of people, etc) semantic markup starts to pay off. But if you're just trying to put together a prototype as quickly as possible, these kinds of frameworks usually speed things up because you don't have to think about proper semantic organization. I've worked on multiple projects where something off-the-shelf like this was the way we started, then at some point as the team grew we re-organized the CSS to be semantically defined. Yes, there is some amount of waste, but this pattern tends to optimize for the things that you need to optimize for in the moment. No sense spending time to carefully design your semantic abstractions until you know the project is going to be a large enough scale to make it worthwhile.


I would say it is the opposite. Beyond a certain project size, semantic html + css becomes unmaintainable because you are not able to predict what while change if you remove one line of css.


If that's the case, then I would say the CSS was poorly structured.


That was sound advice back when we were primarily writing HTML or HTML template language-like things.

Now that people are writing "components" in frontend languages , it makes more sense to reason about styles in terms of those components. That's basically the insight that Tailwind had - can we get the benefits of componentization without resorting to CSS-in-JS solutions? The answer is yes. And we can even bring it to other development stacks by using Post-CSS


My take on this is that documents are different from applications, and so different approaches to composition and organisation are arguably OK.

Personally though, I'd introduce another intermediate set of names - like 'color-brand-primary', 'color-brand-secondary' etc... so you can make branding changes more easily. The majority of Tailwind can be used as-is though.


The `blue-x00` is just the default, you can override which colors are available via the tailwind.config.js file, as detailed in the documentation:

https://tailwindcss.com/docs/customizing-colors


It's definitely feasible to add custom color names (and other properties). I have brand specific color names in an app I'm working on right now. There's a theme object in tailwind.config.js that deep merges with the defaults. Great for setting up custom colors, fonts, etc.


See also: https://twitter.com/thomasfuchs/status/810885087214637057?la...

I get it; there is more than one way to do something--especially in code--and what feels correct for one person may leave a bad taste with another. It's just that nobody has been able to explain to me yet how JSX, Tailwind, etc... are overcoming the complexities that such mixing of concerns introduced before those projects came along.


Let me try to explain: in the past, best practices dictated we should separate things by language because it was the best we could do at the time. Also it allowed for "skinning" websites, which was nice.

But after a while we noticed that wasn't enough, giving rise to CSS methodologies like OOCSS and BEM that aimed at separating CSS by components. We also started doing the same with Javascript, and even HTML using helpers or smaller "per-component-templates" in backend frameworks.

Now, we have components, and that is your "separation of concerns". Modern frameworks like React and Vue allow you to have even smaller components, which means less code. Mixing languages stopped being an issue for most programmers.

If you're still not comfortable, you can still do it: in Vue.js it's quite trivial to have separate JS/CSS/HTML files. But most people have moved past that since small components give them the separation of concerns they need.

Also, remember the skinning part? With SASS/SCSS/native variables, you can now abstract your CSS and keep them closer to the code without losing the possibility to change the appearance.

As to Tailwind, Bootstrap had already paved the way for helper classes. Lots of people used them in a non-components websites and it worked for them. The only issue they had was that helper classes require some copy+paste that would make maintenance difficult. But now that we have good component systems it's not a problem anymore, and Tailwind is pretty good for maintenance.

Also, regarding skinning: with a Tailwind-like frameworks you also get some help with this, since it's the same primary-color class all over the system.

EDIT: Another great argument I read here at HN is that even with Tailwind there is still a separation between content and presentation. It's just that before my "content" was in my HTML and my "presentation" was in my CSS. Now, my "content" is in my JSON while my "presentation" is my HTML/CSS. Tailwind as an extension of HTML makes a lot of sense in this context.


That philosophy works if you have a lot of docs with uniform content that can be represented by simple tags that don't need to change much. However if you have a rich UI then A) there tends to be more structure than content and B) structure, behavior and presentation are coupled together by definition.

Yes you can try to shove the square post into a round hole by naming your HTML just-so, cramming as much presentation in your CSS with pseudo elements, and using pure JS files hooked to HTML via classes/ids, but the minute you need to change anything you'll see you can't make a single change without carefully considering all 3 "de-coupled" file types. Worse, if you try to reuse these semantic definitions across a large app, now you find that a change over here can break things way over there, the larger the app the worse it gets. Once you get to this point you realize that component level isolation ala React/JSX is a much more sane approach to manage huge web app UIs than pretending that functional de-coupling is some kind of platonic ideal rather than just one possible set of tradeoffs.


I felt this way too until I started using Tailwind. I feel like Tailwind (and perhaps atomic css in general) is one of those "don't knock it till you try it" kind of things.

But, with that said, I do feel Tailwind relies on components (such as React, Angular, whatever) to be most effective. You'd ideally stick that purple class in a Heading component and maintain consistency that way.


Been through this process. Thing is, when you have a <Heading> component, you might as well simply write a css module for that component. Tailwind is great for "fast prototyping" and quickly styling a bunch of static HTML though. Wouldn't use it for a larger single page app.


I might be overreacting to past projects, but I've almost always found bespoke css gets out of control. Most projects tame it with well defined values for margin, padding, etc, and applying and enforcing those values means you sort of end up creating your own Tailwind. The "atomic" side of Tailwind is nice, but so is the consistency in values it provides.

If I was to take the css module approach today, I might still find myself using Tailwind and @apply inside the modules.


sure, if you have "a" heading component - but what about when you have 30 heading components?


Is that something that should happen in a well-designed web app?


AIUI Tailwind is an explicit rejection of the previous "decouple content and presentation" dogma. People seem to like it.


Factoring and decoupling parts complex systems is good engineering, but "content and presentation" are the map, not the territory.


it's different in specificity for one. you can also extend the config and create a color called `branding-primary` for example, then use that for anything you need to apply a color to. can do similar with css custom properties or sass/less variables


You still want the ability to customize the size and color of all your second-level headings in one place.

The font example you listed got popular because it was easy and no alternatives yet existed, but became a burden when it got baked into thousands of separate files. Hence the rise of separating markup from presentation.

Now the pendulum has swung the other way, and that original ease of dropping styles right into markup looks quite attractive, while the separation ethic seems overbearing. React's component-based approach has also made it easier to centralize presentation while still leaving it mixed with the markup, which has given Tailwind and similar methods space to edge their way back into mindshare.


I'm still old school enough to appreciate the ideal of the separation of CSS, HTML, and JavaScript but one benefit I do see of the Tailwind approach is that refactoring is a lot easier if it's all in the class attribute.

Let's say you suddenly want all text-purple-500s to be normal weight and red, it's a simple search and replace as opposed to old school HTML where you might need to remove a b/strong tag, etc. It's not exactly elegant but it is at least viable to do quick search and replaces for styling than using presentational tags.


For me, it was trivial to implement a color selector. I basically never use `text-{color}-500` but instead change mine to `primary` `secondary` etc. (I do have some for grays, though).

You can check out my color selector + dark mode selector at the top of my site here:

https://www.listenaddict.com/


Because it's more than six months old, and therefore totally obsolete.


Tailwind sounds like a crazy and backwards concept. It looks insane and I used to feel the same way. However, after trying it and it clicked I can't imagine myself going back. It's one of those things you really need to try before you get it.

Now I find all of these arguments against it like someone trying to convince me not to use syntax highlighting (http://www.linusakesson.net/programming/syntaxhighlighting/). I understand the reasoning but it's not something I would even consider.


This is why I don’t love Tailwind as much as I’d like:

"It gives developers without a deep understanding of design the ability to build visually gorgeous, modern user interfaces."

This is flat out a myth i widh people stop regurgitating. Look, unless you do css as your primary skill or really passionate about the more visual side of things (the "front of the frontend") then you don?t magically have the skills to use all kind of css layout te hniques to do precise and elegant UI, given the sketch / figma files. Heck most JS devs I’ve worked with barely understand how flex works. Best scenario they make somthing close to provided design, but not quite ... and crucially the finishing touches , the consistency , understanding of design principles that inform every layout you make is missing, so the end result is never quit3 what the designer provided with all kind of small but noticable imperfections like incorrect font sizes, une en spaces, missing white spaces, inconsistent vertical rhythm, relative sizes between icons and text etc etc.

Yes, tailwind is good. As a standard utility framework it?s awesome but please stop prentending it turns JS devs magically into css/html experts.


"A deep understanding of design" there doesn't refer to understanding the tools of the trade (e.g. CSS), but rather on how to create a harmonious whole, e.g. by consistently applying paddings, colour scales, etc. Tailwind (and other constraint-based design systems, see [1]) can help with that.

[1] https://styled-system.com/guides/why-powers-of-two/


Yeah, that's a weird point.

Tailwind is CSS. Writing Tailwind classes is writing CSS.


> stop prentending it turns JS devs magically into css/html experts.

It doesn't turn them magically into experts. It gives them the tools to implement complex designs with relative ease, and it helps understand some deeper relationships and concepts in CSS. Speaking from own experience, YMMV and all that :)


> It gives them the tools to implement complex designs with relative ease

The actual scenario is backend / js / "fullstack" devs can copy/paste from many available tailwind "blocks" such as a login screen and it "just works". They didn’t have to wrangle css imports, sass syntax, fugure out dependencies and such.

In that respect tailwind is awesome for majority of devs who work without designs and asked to implement gazillions of admins, dashboards, dialogs, etc.

I fully understand their position and the success of tailwind in that respect. Using eg. bootstrap is already several levels of complexity higher due to understanding where to put the css classes, why they break when you change the html structure, how to fix them, etc. Typical js devs can modify css but often they will do a hackjob, making the css worse. It’s as if they don’t have appreciation for how complex css is and that principles of software architecture CAN also apply incss such as low/high coupling. Much better if they have to "only" edit a template, better for everyone involved i. a team unles. they have a dedicated css expert.

On my last professional project I was able to use both Sass and tailwind.. but even to do that requires solid understanding of css selectors specificity, css best practices, because by default tailwind classes and custom css will compete.

So in my experience whether it’s tailwind or Sass code, non-css developers aren’t any better off when they are stuck with layout issues. They still assign the issue to the css guy ;)

PS : with all that said I am grateful to tailwind as well as bem and SuitCSS for making me appreciate more the needs of the other guys on my team. Writing css / tailwind that doesn’t break easily and is more maintainable that’s the art and what makes me still love the "front of the frontend". Learning to appreciate tailwind which I disliked at first made me, a css expert (and very proficient in js as well) a better overall developer.


> The actual scenario is backend / js / "fullstack" devs can copy/paste from many available tailwind "blocks" such as a login screen and it "just works".

It's that, but also something more. Tailwind blocks are exact opposite of black-boxes. You can clearly see everything they are made of, tweak it and experiment with it in a fully localized manner.

CSS imports and SASS syntax are the least of the problems Tailwind solves (I don't actually think they are problems at all).


Not if they don't understand what those tools do or how to use them.


I mean what's there to understand with tailwind? It's a bunch of CSS classes. You want to add a shadow to a button and the "shadow-md" class. Same with a ton of other things like border radius, text colour, padding etc


It's not about understanding or not understanding tailwind, it's understanding the CSS that it's applying for you. Tailwind is just a shortcut, you still have to know where you're going and why.


There's something to be said about being able to build out an entire component with just using your editor's css autocomplete. The name "tailwind" is really apt once you get the feel for it.

The authors did decide to 'fix' some css naming, such as Tailwind's `hidden` class is `display: none` rather than `visibility: hidden`, which seems wrong at first. But when you see that `visibility: hidden` is `invisible` in Tailwind, it does makes sense. I still can't help but think just following the existing naming might have been better, about my only teeny tiny gripe so far.


> This does require some design taste, but most frontend engineers I know have developed that over the years of building user interfaces.

Nope. Never really happened for me. Admittedly I don't solely work on frontend. But 22 years of making user facing interfaces and I really don't feel more confident about it than I did on day one.


> But 22 years of making user facing interfaces and I really don't feel more confident about it than I did on day one.

You might enjoy "Refactoring UI", which I find to be a good design reference (with lots of specific tactics and examples) for front-end developers. It takes a lot of mystery out of the design process.

[1] https://refactoringui.com/


I think you're probably selling yourself short. I also am a horrible designer, but I've built enough UIs to be able to at least add to the conversation.

I actually consider it part of a front-end developer's job to push back against designs that don't work. There are anti-patterns for users and many of them make life harder for developers (modals launching modals, for example). Some examples from my own life is a designer adding so many columns to a table that it would be too crunched on laptop screens, magic interactions that break a11y, or flows that just don't make sense for seasoned web users. Now that's not to say I can design a great UI on my own, but plenty of good editors can't write a hit novel either.

Most of the time designers are happy for the feedback, because it's cheaper to fix things early on and ultimately makes them look better.

You don't have to be a designer to spot the good and the bad, and I'd be willing to guess you've osmosed more than you give yourself credit for.


There are a _lot_ of frontend devs who don't, especially now that frontend is so much more than "slap some html and css together". I probably just know the wrong people but I can count on one hand the amount of frontend people I know that I would say have an eye for design. It's pretty easy to get by without it. :)


I'd recommend reading "Refactoring UI" (by the authors of Tailwind)


This book: The Design of Everyday Things by Don Norman really helped me with UX/UI thinking


This book is really good... (It used to be printed as "The Psychology of Everyday Things", if you're looking in your library).


It's more common than you'd think. The fact that you still care after all this time and also admit that you can't is actually commendable and very rare. There's nothing worse than an idiot dev who thinks he "has developed a sense". Congratulations on avoiding that fate for 22 years in row ;)


I’ve been thinking about an alternative to tailwind but I have no idea how to implement it.

I think what would be even more powerful is you configure all the classes with some kind of regexp. They need to be unique. You could provide a function as well that returns the correct css for any given captured units in the class name so eg. "mb-4em" you have template "mb-(\\d+)em" declared. The tool recognizes it and either just puts the number there, uses a mapping (4 becomes 16), or calls a function to return the resulting css properties.

What I like about it is you could just as well create more advanced utilities and the parser never generates any classes in advance. It would need some kind of watcher though to detect any new class aded to templates that match the definition file.

Then there would be no need to purge anything. Kind of a vague concept I’ll admit, but for me starting with a figma or sketch where designer typically does not folow a consistent guideline, it means I can just start writing templates and keep declaring utilities as I go because in the real world you bet that happens.


i mean, tailwind kinda does a very simple version of that...`/` is not a valid class character, but it's parsed correctly on compile.


You could do it with single file component frameworks (Svelte, Vue, possibly Angular). Your CSS is alongside your HTML and so your classes could be matched during compile.


Tailwind must have an extremely talented social media guy/growth hacker or be a very good product:

14 HN front-page hits within just one year.

https://hn.algolia.com/?dateRange=pastYear&page=0&prefix=fal...

Edit: Got downvotes, guess what haha


It's a good tool and they have a strong Twitter community.


Not a fan of it myself. I've never understood this desire to avoid writing CSS wherever possible. It's not hard - at least not anymore - but this type of abstraction makes it hard, in my opinion.

On top of that, I think it's just a bad idea to pepper your html with utility class names.

That said, these days pretty much everything I do is React, and styled-components' ability to interpolate props in styles and attributes is pretty darn nifty.


Using tailwind is mostly like using css. It is just a selection of recommended properties and values that hides almost nothing about the nature of css. The abstraction is very thin and its main goal is to limit the "power" of css (complex selectors, arbitrary color or spacing values) to help developers implement best practices.


+1 for styled-components my prefered choice now over tailwind. Styled-components have good integration with typescript - no need for custom utility classes or inline css, also doesn't have a way writing an invalid css-classname and styled-component written css can be easily linted.


Oh my god, it just keeps on getting worse!

Sure, let's take long strings of barely-scrutable utility classes and make them transform into CSS-in-JS statements under the hood via an overcomplicated build pipeline—WTAF.

What I find so ironic is pure, native, truly-modern CSS with properties/variables, Flexbox, Grid, encapsulation via Shadow DOM if you want it, etc. has gotten so-o-o-o good, you barely even need a framework anymore. Stuff like Tailwind feels like it's solving the problems CSS might have had…er, ten years ago.


It feels like the author reinvented the `style` tag.


You're reading it wrong. Tailwind is pure css.


Oh really? Then why is markup written with the Tailwind build process in mind fundamentally incompatible with every other CSS framework/no framework? I've switched entire sites from one traditional framework (e.g. Foundation) to another (e.g. Bulma) in a matter of hours. With Tailwind, that'd be nearly impossible (and the @apply trick in external stylesheets actually makes that process worse, not better).


I'm confused by what you're saying. I've made Tailwind sites that did nothing more than include their single css file from a CDN. Zero build process.

Do whatever makes you happy, I just don't want people who are passing by misunderstanding what Tailwind actually is.


OK, let's say you have a "styled box to hold a blurb of content" and in Framework A it's a single class: "callout". But in framework B, it's called "box".

You can switch your element from "callout" to "box" and likely move on.

But if your element is nothing more than twenty utility classes, good luck with that.

Similarly, if you have a custom class in your stylesheet using normal CSS properties you wrote alongside Framework A, you can use that same custom class with Framework B with little to no modification because it's "real" CSS.

If instead your custom class is twenty "@apply" statements using utility classes, good luck with that.

So again I say: Tailwind is fundamentally incompatible with every other CSS framework/no framework.


Again, this doesn't make much sense to me.

Assuming that we're talking about 3 systems where the html is exactly the same between them, and we just want to add a single class on the outer element in order to style the whole component. I can do that with Tailwind.

    .box { @apply m-4 bg-gray-200 p-4 w-3/5; }
    .box div { @apply mb-4 text-xl; }
    .box p { @apply w-1/2; }
I'm evidentially missing something here.


> I'm evidentially missing something here.

Yes what you're missing is the hypothetical scenario of using 3 full blown CSS frameworks that apparently share the exact same HTML structure for all their components, which we all know is a farce.

Jared here is just trying to make up bunk reasons for why he feels his superiority complex about CSS is best way.


Yes, your ".box" example is 100% tied to Tailwind. Remove Tailwind from your build process, and that stylesheet is broken. So you can transition sites to Tailwind, but transitioning a site away from Tailwind proves extraordinarily difficult.


Wait, that was the challenge though. We were swapping away from Tailwind so another css framework could style the box. Now you want to keep Tailwind? You can have that cake if you want it. Just render the output one time and link to the rendered css. It’s cleanly crafted css that could have been written by hand.


Regarding performance, twin.macro seems like a fantastic approach for React users, inlining the styles where needed with Emotion/similar.

It also answers the "where do custom styles go" question to some extent (answer: the css prop).

https://github.com/ben-rogerson/twin.macro

Edit: I had stopped reading half way through! This is what the article is about. I'll leave my comment up to publicly shame myself.


I'm a really big fan of tailwind as someone who doesn't like to do frontend. It's let me iterate decent-looking proof of concept features and MVPs while focusing mostly on the backend, where previously most of my designs would look like craigslist.


Same here! I am a huge fan of the base styling and components they offer. I even splurged on tailwind-ui, I am super happy with it, and I highly recommend it to others. It is such a refreshing experience to have something other than Bootstrap derived personal projects and MVPs.

To anyone from Tailwind that may read this, please keep up the great work. The easily apparent thoughtfulness and taste that went into tailwind and tailwind-ui are what drove me to try it out, learn it, and incorporate it into projects. I’m excited to see what else gets added to tailwind-ui and the progress on headless-ui as well! If you need any contributors on the front-end side, especially with accessibility, let me know who to reach out to.


I'm in the same boat but I've really hit a painful point where I can do a good job with Tailwind UI components and other things like that, and I can massage and hack on them to get them looking good, but I can't make a great UI.

I'm getting really close to going back to minimalism. A clean modern look with good color scheme and good fonts, without worrying about animations or really fancy components.


Check out tailwind-ui[1]. For me at least, the cost was well worth the value and it’s not much more expensive than the variety of Bootstrap templates I have purchased over the years. It also helps support future development of tailwind.

[1] https://tailwindui.com/


One of the best things about Tailwind (and the component and HTML-first movements in general) is a move towards Locality of Behavior:

https://htmx.org/essays/locality-of-behaviour/

With these approaches, you can achieve a complete understanding of a component in one place, without needing to pick around in a bunch of different places, using id-matching or some other mentally burdensome mechanism to keep everything straight.

There are trade-offs (as the essay mentions) but Locality of Behavior obviously has a lot of advantages.


I like tailwind, but I just used it for small side projects so far.

Something I don't understand yet, is how you would use the "purgecss" feature in a large project or in the context of a company with several teams and a design system.

For example, let's say we have a shared React components library, which has been built with tailwind. Should this shared library expose an already built and purged css file?

Should each of our applications do its own purging? If so, how do I prevent the same m-1 to have two different values, one from the shared component library and another from my own application?

If I have to add node_modules/my-library to the purge directories... Wouldn't that still leave styles for components I might not be importing in my application?

Should I have a shared tailwind.config.js?

These are the things that worry me about using tailwind in a larger context than a small/single project.


> Should I have a shared tailwind.config.js?

Yes.

> If I have to add node_modules/my-library to the purge directories

I believe the point of Tailwind is that you don't have these outer libraries anymore. If you need a piece of UI implemented, you copy/paste the markup with the required classes added. There is no `modal` class that completely modifies specific nested HTML. And if it's a complete palette/padding change, then that happens in the config.

> ...how do I prevent the same m-1 to have two different values, one from the shared component library and another from my own application?

`m-1` should never have different values in different contexts of the same project, unless the set of classes suffixed by `-1` is adjusted as a whole (ie- letting users resize the UI outside of the built-in browser magnification).

> how you would use the "purgecss" feature in a large project

Purge should happen in deployment, not in development. That way if a class is added that has never been used before, it makes it into the site without issue.


> I believe the point of Tailwind is that you don't have these outer libraries anymore

This is a total blocker for this use case then. As a member of one of multiple teams, I won't be able to convince anyone if we cannot have a shared, consistent "Datepicker", "AutocompleteInput", "TagInput", etc...

Copy pasting these components is not an option for us.


> Copy pasting these components is not an option for us.

Uhhh...why not? Have a repo with your versions of components if they're the exact same from project to project, and import them.


It really depends on how generalised your component libraries are. If you want to customise the color palette, you will need to use the same color classes in all libraries, which requires that the `colors` part of the config matches everywhere. Using a shared base config is probably a good start at least.

As purging is only done for production builds, the purge content paths only need to be defined in that projects config. If you are using components from `node_modules` then you should add their paths to `purge.content`.


Yes, but this wouldn't work either. I can add the node_modules/my-library path to be purged, but that means that I still will get included in my application EVERY class used in the component library, despite I might be using just every component or not.

This is a major shortcoming for using tailwind in a company/corporate context in my opinion.

I still like it for my own side projects though.


I think you’ll find that there’s a common subset of classes that are used by most components, and that you quickly reach a point where adding new components hardly alters the built css file at all.


Tailwind's paradigm ("atomic css") is great and the future, but there is a much better implementation, the barely maintained Tachyons is way superior and was also the first that made atomic css popular. I wrote following on Reddit which still holds true:

After 2 days of testing, I chose this stack:

Tachyons as primary CSS-in-JS and media-queries method in my React components; why: it's slick, easy and complete and brings you quite far

configuration is super; eg, creating your own color or default font is just putting them in your App.css and they override Tachyons; creating other breakpoints is possible (just change and recompile, this takes 1sec and a tachyons-cli is there, no need to touch webpack or eject CRA)

however, configuring Tachyons is not required at all, I tested it in and out and it's all perfect at the moment, it's really turn-key and absolutely the right approach to our problem; Tachyons does just one thing and it does is right

I preferred it very much over others like Tailwind because Tailwind has cumbersome and long CSS naming; Tailwind's philosophy and strategy is inconsistent; on the one hand, it wants to be atomic CSS, on the other hand, it bloats and pollutes your components almost like real CSS, wth? either I do minimal atomic CSS (it's called 'atomic'!) like Tachyons or I put real CSS in my component; Tailwind doesn't know what it wants to be while Tachyons has a clear strategy which is perfectly executed => an ultra atomic mapping to CSS, Tailwinds bobs up and down with some short names and then some long ones...; also setting Tailwind up or configuring is unnecessary complex and bloated; doc is comprehensive and complete but also because of its own complications and disunity; atomic css doesn't need to be science; compared to Tailwind, Tachyons is a dream

I also checked styled-system but found the DX not close to Tachyons and couldn't see any benefit over Tachyons; it's too cumbersome but in a different way than Tailwind

Tachyons is just 13kb gzipped while fully featured (Tailwind is 36kb)

while small Tachyons has the biggest ecosystem (related libs, cheatsheets, blog posts), at the end of the day, you don't need more, again it's just a mapper and more advanced stuff should be done with eg Emotion anyway[1]

[1] https://www.reddit.com/r/reactjs/comments/a6qhbr/checked_21_...


Tachyons does it well


i'm trying to find it in the docs - but how do you apply a different border on mobile, tablet and desktop via tachyons?


An ineffable truth of webdev is that it is constantly disrupted by morons who claim to have an improvement, but really just want as many people as possible to use something THEY built.


People who seek disruption will find it.


I wanted to try tailwind on a new CRA app but they’re using a version of postcss that just came out and has a bunch of compatibility problems.

> As of v2.0, Tailwind CSS depends on PostCSS 8. Because PostCSS 8 is only a few months old, many other tools in the ecosystem haven't updated yet

There’s a workaround but it seemed like something I’d have to workaround more than it was worth.

https://tailwindcss.com/docs/installation#post-css-7-compati...

https://tailwindcss.com/docs/guides/create-react-app


FYI: PostCSS 8 + Tailwind 2.0 is compatible with Next.js.

You can run `npx create-next-app --example with-tailwind` to get started.


Use tailwindcss@compat (instead of tailwindcss) and that's it.


Tailwind is not for me, simply because I don't want to have to learn yet another DSL that may or may not be abandoned in the future. I understand this is a personal decision though, but I've been burned too many times by fads.

My ideal CSS solution which doesn't seem to exist yet:

- Be able to write plain old CSS in JS/TS directly within a React component's tags, with a JS object literal

- Automatically generate atomic classes for each CSS rule (or block of rules) and have the system reuse those rules when the same styles are used elsewhere (no rule duplication means smaller bundle sizes for SSR, plus you get the semantic clarity of using plain CSS rules)

- Compiled, with zero or near-zero runtime overhead and critical path extraction, all cacheable by the browser. I don't want a huge runtime just so that I can dynamically apply a background colour.

The thing that comes closest to this is probably something like Linaria [1], but it relies on tagged template literals instead of object literals which means I can't use autocompletion. Their API for dynamic styling also relies on HTML data attributes, which is a little clunky.

Stiches [2] is another interesting project, however adoption doesn't seem very high and it seems to create superfluous wrapper nodes which can cause performance degradation in large VDOM trees. There's also no mechanism to colocate styles within a component's tags.

CSS Blocks [3] looks very promising also, but it doesn't allow co-location of styles with React components (you need to make a separate CSS file for each component).

[1] https://github.com/callstack/linaria

[2] https://github.com/modulz/stitches

[3] https://github.com/linkedin/css-blocks


Facebook's stylex might also be interesting to you. No idea when (if ever) they will release it, but one thing it does is compile all the css down to atomic classes

https://www.infoq.com/news/2020/04/facebook-cssinjs-react-co...


Definitely keeping an eye on Stylex! To me, it looks like the optimal solution to the CSS styling problem.



Genuine question, I'm a dev, but primarily backend and all my frontends are internal/chunky/it doesn't matter

I usually do 2 things when styling my crummy internal sites: a) manually write semantically-named classes for things that need it ("help-text", "external-link") and b) just in-line styles for everything else (esp. when a style really only applies to one element, or is intimately related to important layout considerations).

It seems to me that css classes which contain styling info in their name (h-32, font-semibold, text-cyan-600) aren't really any better than just in-line styles, and in fact maybe worse because they [seem to me] to just be an alias [which I have to learn, and will forget later] for a css style. Wouldn't it be simpler to just inline the style?

So my question is: what's the real benefit of this kind of css framework? What are the scenarios where it really helps to do styling this way? Is it just a performance thing? Is it about streamlining a dev workflow in some way that I don't get?


It helps streamline the dev workflow, absolutely. At a very basic level, it's much faster for me to write "p-4" than "padding: 1rem;".

A big benefit I see is the constraints it introduces. If another developer comes along, they know there are a few options for padding. Rather than guessing and setting some pixel value (or should it be in em, or rem?) or having to refer to other code or documentation, they can just look at a design document and say "that looks like a p-4", done.

Tailwind also makes things much more flexible than using inline styles: I can add a brand colour to my Tailwind configuration, and I immediately have utility classes available for text, background, fills, hover and focus states, etc. I can update one hex value rather than refactoring every inline style in my app. You could do this with custom classes, but frameworks like Tailwind mean I can hire a new developer and they don't have to look through a stylesheet and memorize potentially hundreds of style definitions and class names. I think this standardisation can be very useful.


Bingo! There is really no reason not to use it considering everything you just described, I don't know why people in this thread have such strong opinions on this? Maybe it's from years of seeing the new "fads" which repackage old, stable solutions and call them a new thing. I have yet to read a comment on this thread which makes a good argument to not use Tailwindcss.


There might be more, but the first that comes to mind is "snapping". To pull from your example, `h-29` through `h-31` don't exist, meaning you have fewer options and will settle on one of the standardized heights. Similarly, `cyan-501` to `cyan-599` don't exist, so you don't accidentally settle on a slightly-different shade.


Tailwind itself has this [0] to say about inline styles vs utility classes.

[0] https://tailwindcss.com/docs/utility-first#why-not-just-use-...


Naming the classes forces consistency (cyan-500, not a random number you could get wrong) and works with media queries. FWIW, the Tailwind devs say you should just use an inline styles for one off things like "this SVG needs to be pushed 41px off baseline".


text-red-500 isn't the same as color=red, and you can override which shade of red that is (or make it green/brown/whatever...tho that would be silly). but you can also define brand-centric names for stuff and they apply to anywhere you'd be able to use a color (text, border, shadow, etc). there's also the notion of having a design system, rather than a prescriptive framework...tailwind comes with some sensible defaults on these things, but it's built in a way that you can override it all to suite your org's look and feel.

with that said, it's an internal tool - who give a hoot?


> The key to Tailwind's popularity is the painstakingly constructed system of design tokens at the core of the framework. The system's carefully selected constraints give developers just the right guardrails. They make it obvious whether a choice is good or bad by offering only discrete steps.

Can anyone comment more on this? As far as I see, there's still a big enough range of font sizes, padding/margin sizes, colours etc. that you still have to have an eye for design for the result to look pleasing. I've seen multiple landing pages made in Tailwind for example that don't look good.

Bootstrap in comparison will have a really uniform look if you use the built-in components, but you won't be able to build something that looks as good as Tailwind.


Semantic-UI [0] is also a well established framework for building up design using css classes and html only.

It's been more or less abandoned when the main developer got tired of it though, I really hope the same doesn't happen here.

[0] https://semantic-ui.com [1] https://fomantic-ui.com (Community fork)


Mhh... I don't know how to feel about this.

Over the last year, I've shipped a bunch of (p)react components [1, 2, 3] and what is cool about them is indeed that you can now encapsulate a UI function and make it re-usable within your project or even across projects.

In theory, this should finally give front end devs the same super powers as backend devs: high reusability.

However, a problem that I wasn't able to distinctly address is CSS. Currently, there's simply too many variants of encapsulating CSS into a "react module". You can opt to use:

- css modules

- styled components and derivatives

- CSS in JS or classes in JS, etc.

But ultimately, if you build your UI as a patchwork of many integrated UI elements (which IMO should be something legit in frontend development), you'll end up having to include 5 different CSS-in-bla libraries either in your build pipeline or (worse) in your bundle code that you ship to production (bloats the size and hence your app's performance).

Long story short: Combining styled components with twin macro and tailwind doesn't make my life easier currently. And the benefits to my users will not be apparent directly either.

Not to say that all the CSS-to-XY movement isn't cool. Still, I think the best solution to this problem has yet to be discovered.

1: https://github.com/TimDaub/preact-touchable-dock

2: https://github.com/TimDaub/react-envelope-graph

3: https://github.com/TimDaub/react-simple-knob


My concern is that people might get too complacent with libraries that claim to make CSS local, and people might get lazy and all start using the exact same "generate a unique id" library, which will then start generating a ton of the same id across multiple users of that library.


Can anyone recommend any text-heavy tailwind themes? Or - are themes even viable with Tailwind?

I'm a backend Dev who plans to buy Tailwind Build (or w/e it's called). I enjoy the idea of not having to worry (as much) about design, and instead just focus on content layout, etc. Tailwind is neat that way.

With that said though i'm not a fan of the .. "modern" design. I'll use it, i guess, but on text heavy pages ala Wikipedia or HackerNews, Tailwind looks like it would waste a lot of space. Though maybe i'm off base.

The point of this is to ask if theming has gotchas. Eg maybe themes work, but they're rarely ever supported well enough, leaving you with little gaps in design that cause problems. Thoughts?


Consider Tailwind not as bootstrap, but as something to make your own bootstrap (like flask -> django).

In short, is only bulding blocks with some option to pre-configure the base defaults (https://tailwindcss.com/docs/configuration) and pre-seed the theming (https://tailwindcss.com/docs/theme), if wanna get low level.

Is like functional programming: You get for "free" the higher-order functionality but left to you to decide what to do with the building blocks. You can totally make your own components ala bootstrap (https://tailwindcss.com/docs/extracting-components).

What this make interesting, is that you can do it at HALF.

For example, you can decide that "components" only are the shapes, but you must supply colors and dimensions. Or are colors and dimensions, but your must supply the shape (etc: As building block, you can mix-match).

---- P.D: I'm building a niche ecommerce platform and TailwindCSS is far easier to theme than bootstrap, by a long shoot. Specially because in my case, my customers only care for "colors" than overall shapes, so I can hand-code the site visual structure and left colors and cosmetics open.


I purchased Tailwind Components Application UI, I'm pretty happy with it. Had zero problems so far and I'm having a blast when customizing.


Asking since I’m working on something in this space..

Why tailwind and say not Bootstrap?

And can you elaborate on the text heavy pages?


Disclaimer: I'm super not design focused, statements made below are assumptions, feel free to correct.

> Why tailwind and say not Bootstrap?

From the un-researched outside i don't understand how much of Bootstrap is pure CSS and how much depends on JS. I know when i've used Bootstrap in the past i saw a lot of JS, which turns me off. I primarily want a light CSS framework.

This is coupled with the fact that UI executed logic is handled by WASM in my use case (Rust). So the thought of decoupling JS puts up mental friction that Tailwind doesn't give me the impression of.

Sidenote, i've tried some of the Bootstrap ecosystem in the past and it felt rather messy. I imagine this is partly due to the success of the Bootstrap ecosystem, but it felt messy enough that i'd probably only be interested in a streamlined CSS only Bootstrap offering.

> And can you elaborate on the text heavy pages?

I guess i just mean pages where i want to see more dense information, like Wikipedia, rather than more sparse information which is common these days.

An easy comparison is New vs Old Reddit. A lot of design i see, even from Tailwind, organizes UIs like New Reddit. That might be nice for landing pages and customer navigation - but i loathe it for data. When i'm viewing long for data i want to see things both look good and be densely packed - within reason. New Reddit takes high volume information (lots of links/descriptions/comments) and makes navigating it ~5x less efficient.


I like TailwindUI. Of course, made by the creators of TailwindCSS. A bit spendy, but worth it.


I'm personally a big fan of Tailwind + either HTMX or Alpine.js, as it lets me easily generate modular UI components in the back-end using the 'dominate' Python library, without having to fuss around too much. (Other frameworks such as React should work as well, I just haven't experimented with them very much so far).

Munging these tools together has let me create my own 'distributed back end framework', so I can define back-end logic and front-end logic in the same place, but have the back-end logic run on whichever machine I choose, so e.g. an edge device can send a fragment of UI to a monitoring dashboard.

It's all rather nice and I'm very pleased with myself. :-)


Was always curious, why it was Tailwind that won 'utility-first css' and not https://tachyons.io which did this approach first.


Exactly! Tachyons was awesome and ahead of its time but its core design system wasn't as well made as Tailwind's is.

Also, to be fair, Tailwind's marketing game is out of this world as well. They are literally some of the best developer marketers on this planet!


You can create (or recreate) Tachyons using Tailwind, and take advantage of all the bells and whistles that the later offers that the former does not.


Can you give some examples of what they did marketing wise that helped it being adopted more widely than Tachyons?


Adam Wathan actually wrote about it:

https://adamwathan.me/tailwindcss-from-side-project-byproduc...

I think one of the most powerful things was making a course then giving it away - really goes far to boost your prominence as a developer and building those lists.


They wrote a book that is pretty popular. Thanks to their connections with the Laravel leadership they got Tailwind as a somehow default for the front-end in Laravel. I dont know if it is organic or not, but there are dozens of articles about Tailwind coming up daily in sites like Medium and Dev.to.


Have you seen the trailer for Tailwind 2?

https://youtu.be/3u_vIdnJYLc


Tailwind is also like half a megabyte minified and zipped vs Tachyons 20kb.


But who uses all those tokens from the full tailwind build? Maybe if you use the CDN build?

That's why purgecss is builtin. It's dead simple to setup and you'll have only the used classes in your CSS output.


I agree, I've just seen this kind of thing before and have low expectations of what people will do with it.

Basically I'm expecting people to be lazy and use the full thing. Especially the CDN build.


I think the biggest thing is documentation. Tachyons has basically none, the only way you would even know that you can do responsive design with it for example is by reading all of the CSS.

Case in point from this very thread:

> i'm trying to find it in the docs - but how do you apply a different border on mobile, tablet and desktop via tachyons?

https://news.ycombinator.com/item?id=25333465

You can't cross the chasm from early adopter tinkerer types to the more mainstream community without teaching people how to use your tool.


I think it's because of the hardcore minimalism of the creators or Tachyons and also Theme UI, it lacks mass appeal because of it. If you dig into Steve Schogers style (the guy behind Refactoring UI and Tailwind aesthetics) you'll see that he's more in the Streamline Moderne camp than Bauhaus minimalism, his stuff looks more "designed" in the sense of how non designers think about good design. Tachyons is kinda invisible..


Ha, you kids! What about the REAL project that kicked off atomic styling: https://acss.io pioneered by Thierry Koblentz and friends while at Yahoo.

Everything that came since is just a variant, in principle, of that. It never gets the props!


Tailwind creator is mates with the Laravel creator so got a big boost in eyeballs from that. I guess Tachyons didn't have that.

If I can be honest the name is a pain in the arse to remember too


great documentation, good 'outreach' presence around the interwebs from the team, sensible class naming (tachyons can get a little...eh, imo), the build possibilities are quite nice (tho may be as flexible in tachyons...haven't used it in quite some time), responsive everything (mostly), the laravel bump as mentioned - all in all an evolution of previous attempts that resonates better i guess.


Great marketing (and this is from a huge fan of Tailwind). Marketing, even for OSS projects, is incredibly important.


I still use Tachyons which I find way better. It*s just a css mapper with much saner design decisions.


    Atomic CSS is not ideal for performance. No tooling can extract the per-page critical CSS, so you end up shipping more CSS to the browser than necessary. The bigger and more dynamic the app, the more unnecessary code you will ship.
Isn’t this solved by using PurgeCSS? During your build phase it removes any unused classes from the final build. You end up with a single CSS file, which is usually quite small, that your browser only downloads once and then caches it.

Do people actually generate a CSS file for every page?


Yes, CSS-in-JS actually generates critical CSS for every page and user! Quite mind-blowing, right? That's possible because it knows exactly which components were rendered in which state, which no other tool can do.

See the footnote in the blogpost that explains this more in-depth. I'll copy and paste it here:

> CSS-in-JS automatically extracts the critical CSS for the requested page and inlines it into a <style> tag. That means the first-paint with CSS-in-JS will always be faster as it saves both an extra network request for the .css file as well as sending less CSS code to the client. While the Time To Interactive for small apps will be slightly slower (as the JavaScript bundle includes the CSS-in-JS library you use) once your app grows the network request for the larger CSS file can outweigh any CSS-in-JS library and can cause a slower Time To Interactive as well.


Interesting thanks! Wouldn’t this only be a benefit for the very first request when it has to download the css file? Seems like including online styles would increase the page size of every page, on every load, versus a one time delay downloading the css?


The problem is partly that page speed measurement tools care a lot about that first load. Even if everything after that is super snappy due to cached resources, if you are only using 5% of the total CSS file in the first page the user hits, that other 95% is dragging down the experience on first load, and especially dragging down lighthouse scores.

It doesn't mean though, that you can't have a combined approach where a small amount of genuinely global CSS is loaded from an external file that is cached, while component-specific CSS lives in the component and renders inline with it. But then it's like ... why do that extra request if the file is that small, and you end up with inline everything.

Definitely the trend from a business point of view is to optimize for good perf scores on lighthouse, even if that's a little illogical at times.

Another thing though is that often the JS for whole chunks of a page (which contains the CSS) can be code-split and cached as its own file, so whole components made up of HTML CSS and JS can be lazy loaded and if that same chunk of stuff is needed again, it could be a cached JS file.

Especially if these are "below the fold" and pulled in as the user scrolls or something, you get a small initial payload + small JS files being called in to run as needed.

I don't know how many implementations there are of this in the wild, but it's possible.


I think the original concept of using inline styles in your React components was truly a leap forward in terms of styling DX. It seems like most of the developments since (CSS in JS, Tailwind) have just been more inefficient ways of implementing that core inline styles concept. Ok, these new solutions give you pseudo classes, but those can easily be replicated in JS. Beyond that, I don't see the upside of the additional complexity these solutions bring vs plain inline styles.


not related to the article at all, but figure I'd share this thing that was recently released (no affiliation, just a fan of marcel's work) : https://usewindy.com/


Thank you for posting this. I posted the link a couple of days ago on HN, but it didn't get much attention back then :D Cool to see that people like it!


have yet to try it out myself actually, but it's on the short list once i get some time at work :)


Whoa this is really cool


Any alternative to Tailwind UI? I can't justify that price for hobby projects. I'm also not interested in material-ui which is becoming open-core.


Checkout awesome tailwind[1], there are lots. tailwind.build, https://mertjf.github.io/tailblocks/ etc. Also hobby or not, the time saved is no joke.

[1]: https://github.com/aniftyco/awesome-tailwindcss#ui-libraries...



I really like Tailwind but has anyone figured out how to get it to run quickly in development with Webpack?

For example Tailwind 2.0 out of the box produces around 3.5mb of CSS and Webpack 5+ on an SSD takes 5+ seconds to start things up. This is a problem with Docker because if your main app container needs to be restart it involves stopping Docker Compose and then upping things. This means your app is delayed 5+ seconds from starting. In production it's no problem with purge CSS and your build step producing the final assets out of band, but I think having a top notch dev experience is really important.

You can do some hacks around how Tailwind imports its fils to make CSS updates happen nearly instantly but the initial Webpack start up time still suffers.

Currently I get around this by enabling Webpack's filesystem cache but this seems like a band-aid solution.

Any suggestions?

On a non-SSD machine I noticed the start up time being 28 seconds btw. It's a non-issue for me but if you want to make open source projects that others use, a ~30 second start up penalty in development is a killer for a pretty large chunk of people.


I’m not sure if it would fit into your dev stack, but letting Tailwind be handled by a Makefile might help. Or, really, any build tool that can use timestamps to determine if a build is needed.

I’ve got a setup like this for a couple Eleventy projects, where it kicks off ‘make’ before starting the dev server. Most of the time, make will finish instantly because I haven’t changed the CSS source. Here’s the file I use in case it helps: https://gist.github.com/dceddia/be4d0f136a340359a57a52f16893...


Thanks. Yeah I was hoping to avoid having to decouple building Tailwind from Webpack as it does complicate the process by a fair bit.


The one criticism it's valid to level at Tailwind is it doesn't play nicely with the CSS cascade.

Take their plugin, https://tailwindcss.com/docs/typography-plugin. It lets you define text styles for regions (handy when you render Markdown into a div, for example).

Imagine that you have HTML inside that div, with TailwindCSS classes applied. The specificity of the text styles for the region override the classes, which isn't what any end-user wants.

The guys behind Tailwind acknowledge this, but there isn't a good solution for it. It's not a TailwindCSS-only problem; I've written plenty of CSS by hand which has this issue.

But when choosing a framework based around element-level classes, this is a limitation which is important to keep in mind.


In https://news.ycombinator.com/item?id=25305467 there was talk about the PETAL stack of which Tailwind is a part. It consists of Phoenix, Elixir, Tailwind, Alpine.js, and LiveView.


It is entirely possible to have a "semantic web" and tailwind at the same time.

IMHO the perfect combination is BEM naming that is purely semantic combined with tailwind cruft that is purely visual.

So you can end up with:

  <div class="profile_card a-bunch of-tailwinds classes">
     <div class="profile_card__heading more-tailwinds-classes">
        <h3 class="even-more-tailwinds-classes>Hello World</h3>
     </div>
  </div>
I say this as someone who was revolted by the idea of tailwinds that has then seen the productivity of the team at work absolutely skyrocket after using it.


I also love tailwind! To me it feels like the defaults are sane enough + an amazing documentation which summarizes all the CSS I use.

Most of the time I think:

"I need a small margin on the right and a big one at the bottom, and let's see a black background" which is super cheap to mentally translate to "mr-1 mb-10 bg-black" while staying in the HTML. If I'm repeating too much I can either move that to a custom tailwind CSS component or a react component. It just feels easy working with, and it's super flexible.


> To me it feels like the defaults are sane enough

I found the exact opposite. If one has perfect defaults it's Tachyons.


If I had known it, maybe I would've tried it. I gave a quick glance to the website and didn't fully understand the idea behind it :/


I still think that this kind of approach it's only a "problem moved" from CSS to inline HTML, which makes me mad because i still need to jump from HTML to CSS all the time, plus custom modifications can be painful with tons of overrides and "!important"s. Exactly like bootstrap.

BEM (with none-to-few utility classes) was a game changer to me (even if far from perfect) and its most natural conseguence are web components.

I'm loving the Bulma approach BTW.


Tachyons needs this for a button:

  <a class="f6 link dim ph3 pv2 mb2 dib white bg-black" />
Anyone so quick to show the same in Tailwind to have a comparison?

You can see the button rendered here (the first at the top): https://tachyons.io/components/buttons/basic/index.html#0


    <a class="active:opacity-80 bg-black hover:opacity-50 inline-block mb-2 px-4 py-2 text-sm text-white transition-opacity">
        Button Text
    </a>
https://play.tailwindcss.com/rNUrXntEZQ

Edit: That should be `focus:opacity-80` instead of `active:opacity-80`.


not exact, but from one of my buttons

flex bg-black text-white px-8 py-4 font-bold cursor-pointer items-center justify-center

edit: more characters needed, but IMO makes more sense as to what it's doing.


I've not yet tried Tailwind, but I've found the utility classes in Bootstrap to be really useful. Over the years I've encountered a good number of instances on larger sites using traditional/global CSS where a change to a particular style ends up unintentionally affecting random stuff elsewhere. It's really irritating.


A design question if I may. Site states "gives developers without a deep understanding of design the ability to build visually gorgeous, modern user interfaces".

I really don't understand this statement. If you are bad/good at design, how does Tailwind change anything? Can anyone please describe what it is/feels like in comparison?


Tailwind is a system for design. It constrains what options the designer has to work with. This means both less chances to get things wrong and a smaller domain to wrap your head around.

Tailwind is configured out of the box by some very excellent designers. The color palette, fonts, spacing, etc. are all crafted to work together harmoniously. You have to go out of your way to configure it poorly.


So it's a _designed_ system then ;)


It kinda doesn’t, it’s nonsense really. They’ve got good examples though (see TailwindUI) and you can directly copy html which includes the css classes and you’ll get their design exactly.


My opinion moved from liking tailwind to loving it when tailwindplay got realsed (play.tailwind.com). It's so cool, and faster than any hot-reload ever will be. It's in my opinion is the smoothest way to create UI components on the fly with ease that of drag and drop tools, but with much more extended functionality.


I'm not convinced to Tailwind. Can someone explain to me how this is better than "normal" CSS? Take this example from the play site:

3 bullet points, each has to repeat the same thing:

<li class="flex items-start"> <span class="h-6 flex items-center sm:h-7">

<li class="flex items-start"> <span class="h-6 flex items-center sm:h-7">

<li class="flex items-start"> <span class="h-6 flex items-center sm:h-7">

vs classes:

<li class="bulletpoint__container"> <span class="bulletpoint">

<li class="bulletpoint__container"> <span class="bulletpoint">

<li class="bulletpoint__container"> <span class="bulletpoint">

And when you have this all around your project, and then you decided to change 1 thing. How Tailwind makes it easier here?

I tried to inspect the Tailwind styles in browser - sorry, but it looks like nightmare.


It's worth noting here that the issue isn't duplicated css, but duplicated html. Ideally, this is handled by some other templating / component library (e.g. React).

The idea is that if you have `bulletpoint__container`, that's going to be specific to this component only and hard to re-use in a different part of the application.

It seems like Tailwind's main value proposition is that it forces developers to select from a limited, pre-defined set of options in styling which can then be used as building blocks for components. It basically circumnavigates css entirely to the extent the page can be styled using Tailwind's options.

As far as I can tell, it's not really aimed at eliminating code-duplication per se. That should optimally be handled by whatever is generating your components.

This article https://adamwathan.me/css-utility-classes-and-separation-of-... explains it better.


Ok, the said article tells that it was not meant to be used in React or similar front-end stuff, but more in things like Rails. But even disregarding that, you might want to have multiple places with lists, or other elements that I guess would not be 'big enough' to become components.


I think you meant to link to https://play.tailwindcss.com


Nice, instant live previews as you're toggling through IntelliSense is pretty slick.


even just using the element classes option in dev tools makes for rapid prototyping


I've "learned" CSS through Tailwind, was using it for a couple of years and I'm now able to build my own design systems in CSS. The reason I moved on is that I wanted a slightly more opinionated system and a different naming scheme, especially for colors.


The only good use case to use something like Tailwind CSS is that your CSS does not grow exponentially and using twin.macro you lost that.


Love it! I've meshed so completely with tailwind on Rails that it put me off learning React. Guess there's no excuse now


I don't understand why people treat it like a new bootstrap


Because people (including me) want something that looks nice without doing any work.

Bootstrap met that; Tailwind looks nicer than the Bootstrap output, and is very handy to use to tweak everything.

I'm ambivalent about the approach. So far the bigger problem is it moves too fast - with Bootstrap I can work on projects over a couple of years and nothing much changes. With Tailwind, it's new stuff every couple of months :)


What do you think of Tailwind vs Tachyons ?


Last time I checked Tachyons (before Tailwind ever existed) there was no easy way of configuring it. The recommended way of, say, changing the stock colours was to do a find&replace in all of its css files. Not great.

I moved to Tailwind when they released their first 0.x version because of its configurability.


What is Tailwind's performance like? It seems like a ginormous CSS (and JS?) blob for a rather simple visual design.


It's actually pretty good. Just have to make sure that purgeCSS is setup property to remove any properties you didn't use.


purgecss and customizing the config will reduce any file size concerns you have (plus gzip, etc) - from an execution perspective, since you're only using a fixed set of class names, the parsing is quite fast.


The text flows outside of the box in the very first example of why Tailwind is great. Viewed on mobile. Not convinced.


I'm not sure that this blog post uses Tailwind. The CSS rules don't look like Tailwind, but the build process might be mangling rule names.

Also, remember to critique constructively:

>Please don't post shallow dismissals, especially of other people's work. A good critical comment teaches us something.


Correct, my blog is not built with Tailwind (yet). I made it many years ago before Tailwind was a thing!


The critique was pretty specific, though? And if a framework that aims to be the pinnacle of CSS makes it easy to get the basics wrong, how is that shallow?


Fixed, that was my bad with the example!

I didn't include Tailwind's reset for the example as that was causing issues with the rest of my site. I forgot to add the word-break rule that it includes!


> flows outside of the box in the very first example of why Tailwind is great

It's just greater than that particular box :-)


I spot many comments either stating that "Tailwind doesn't respect the whole point of CSS: separation of data and presentation" or "CSS falls completely short."

I think the truth is to be found somewhere in between.

This debate is really about what people want and how they envision the Web. Either as hypertext documents that link information; or as a platform for "rich web applications."

While people argue over the problems JavaScript pose when building applications. The same type of arguments also pop up when it comes to CSS. How the focus on semantics hampers building rich applications with a dynamic DOM structure.

I posted a comment a few days ago that goes into detail about this. I hope you will forgive me for repeating it here. I feel it's relevant to this discussion as well.

What changed over the past 30 years is how the Web evolved from a small group of academics and engineers 30 years ago into the billions that it connects today. It's not just hypertext. It's hypertext and every other conceivable business case which is being shoehorned into the browser.

The Web originally wasn't conceived to provide affordances that allow for "rich media experiences". Foundational technologies - HTTP, HTML, CSS, JS,... - weren't originally designed to build complex user interfaces and applications. Yet, as more and more and more people got connected: that's exactly what they wanted.

Remember Flash? Or Java applets? Or Silverlight? Those were hailed as additional technologies that would merge complex user interfaces into the Web. Macromedia coined the term "Rich Web Applications" back in 2002. All of them failed for various reasons.

Ever since the Web Standards moving of the mid-00's, communities of designers have taken CSS and HTML and tried to bend and use them in any way possible to bring visually stunning experiences on the Web. This is where you will find the direct roots of many ideas and dynamics that are currently in vogue. It's their influence, as well as other dynamics - e.g. the introduction of the smartphone, the rise of big tech - that has defined how browser technology has evolved.

Over the past decade, browser vendors have tacked on additional browser API's on top of the original, decade old foundations, while communities of frontend developers have spawned ever intricate constellations of interlocking JavaScript libraries and frameworks that specifically try to break out of how the Web originally was intended to work.

Some things have become easier as specifications evolved a bit (e.g. CSS3). But at the end of the day, your browser still needs to download HTML, JS and CSS, parse all of that, execute and render it onto a canvas.

Tailwind solves a particular issue: it tries to do away with the semantics of CSS and abstracts how presentation relates to the DOM structure in order to allow developers to focus on what they should be building: rich, highly interactive applications.

Tailwind, however, isn't the right tool if you want to focus on building classic hypertext documents / websites. It's still totally valid to build things using the original web standards principles.

It's not a tale of one or the other. It's a tale of both are valid business cases. I think that should be the core take away here.


I am new to Web development/design and I was wondering if anyone was going to make explicit mention of the divergence of practical intent (Web Docs vs Web Apps) and the role that browsers, standards and business play into it all. The first chapter of "Dive into HTML5"[1] was a big eye-opener for me on the nature of the Web's development.

I appreciate your input a lot. Personally I consider myself a proponent of classical hypertext. The massive accumulation of Web apps driven by brand and business and the collective groans that many make in response to it, perhaps is a result of a dearth of a consistent cultivation of informative Web documents.

Your comment lead me to browse some of the others that you've made here and it has occurred to me that you have authored some of my most favorite remarks from the past week or so.

I repeat -- your input is appreciated.

[1]: http://diveinto.html5doctor.com/past.html


Met too


I like Tailwind because it’s the best solution of the bunch at the moment. But I much rather work on iOS over HTML. Now why is that?


I'm not sure what you mean by "But I much rather work on iOS over HTML. Now why is that?" can you clarify?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: