473 comments

[ 2.9 ms ] story [ 305 ms ] thread
Geeze, this homepage is truly world-class. Props to the Tailwind team!
What homepage? This website makes one of those noob mistakes that many off-domain blogs do, in that their logo doesn't link to tailwindui.com.

I wonder why they used a blog off-domain in the first place. blog.foo.com is so 2005. foo.com/blog makes more sense.

Come on, surely you know I'm talking about https://tailwindcss.com.
Now that you've confirmed it, yes. They have two websites and two home pages: foo.com and blog.foo.com
I've been writing CSS since the beginning of the web2.0 days and so it was really hard for me to adjust to the Tailwind approach. It's by no means perfect, but after working almost exclusively with it (and Tailwind UI) I am a big believer. I find myself wanting all the utilities almost immediately as soon as I am back on any other project/codebase.
Yep. Can confirm. It took a while, but I'm sold. Also, the VS Code tooling is excellent.
Their marketing is good, they do a primo job at conveying the message in a nice looking way, but the end result is still HTML littered with hundreds classes, that gets hard to maintain and impossible to refactor.
I'm a big fan of Tailwind because I've realized that HTML isn't really maintained and refactored anyways: it's either composed or rewritten. Rarely do refactors happen in the same way as most programming languages.
Depends on the kind of work, for me, in the kind of long-running web software I make HTML is actually maintained or refactored.
For this use case, the "tailwind solution" is to use components, either Angular, React, or whatever, but to pull those "hundreds of classes" into reusable chunks that could be refactored.
(comment deleted)
I found the promotional video for v2.0 somewhat silly. Epic music taken almost from some Nolan trailer playing in the background for things like "New color palette", "New shades of Gray".

Edit: here's a stark contrast of another promotional video for some tool doing a better job (IMO): https://www.youtube.com/channel/UCaNsjhUdh3BxFL6tzyuhc9g

That's literally the point: it's silly.
Framework author here, yep the whole point of the trailer is to be absolutely ridiculous.

The music was custom scored for us by the best man at my wedding, and we had a professional opera singer record all of the chants at the end which are literally "utility first" in Latin.

It's completely outrageous and absurd :) It's the Old Spice commercial of launch videos.

I've gone through the following phases:

1. Write old school circa 2008 CSS.

2. Oh shit, it's a real pain in the ass to do layout and make a responsive grid. Let me use a framework. Sweet!

3. Hmm.. its kinda painful to write css selectors all day long. They're reusable but I am having to get out of comfy JS IDE setup to go change some CSS properties in a different file.

4. Tailwind arrives. OMG. This is awesome! Never have to leave the context. Just stack properties as you like and compose your components!

5. HTML looks completely unreadable. It's a goddamn mess.

6. I want to go back to 2005. No frameworks. Just write non-responsive CSS, one for each screen (yeah, you read that right. I don't want to compromise the layout for responsiveness. I'd rather handcraft one for each device size give or take a few pixels). Custom crafted like a piece of fine art. CSS grid/layout is a lot better with css grid and flexbox. Things have improves since the 960-grid days. No frameworks at all and its fucking liberating.

Edit: I currently use reset/reboot css to clean up default rendering + sass (only use variables + mixins). I am happy like a daisy.

What benefit does having completely readable HTML offer?
The same benefit as any language you program in. Readability (not saying tailwind is hard, but it can be messy) is one of the most important things I look for.
If you use prettier or similar readability isn't an issue. I'd argue readability is improved since you can tell right away how an element is going to be displayed vs having to open up the css and look there.
What benefit does laying out your circuits cleanly offer? It's pride in your work, a tacit invitation for people who aren't you to look at it. From a functional perspective, does it matter? No, it doesn't really. But it might help you sleep better at night.
Why? Because it makes the document readable... for machines.

You may think about browsers, but if your HTML is a mess, devices that translate content into Braille or read it as audio, won't be able to make sense of it.

That might not sound like a problem, but this might very well cause legal issues in some business cases (e.g. people with an impairment can't access a website of a public administration? That might be a civil rights violation in some countries).

Another reason is because it makes it easier to extract data and information from HTML documents: search engines and search spiders. If your HTML is a mess, you're going to take a SEO hit.

That's just two concrete concerns that come to my mind right now.

HTML and CSS today are mostly used for presentational & interactive purposes: push UI components in there right place, with the desired shapes, colours, fonts, animations and so on, in order to build complex interactive applications.

But HTML wasn't originally conceived for that purpose. The word "markup" says all you need to know. The entire purpose of a HTML tag was simply to describe the structure of a text document: this bit here is the header, that bit is a paragraph, the next bit contains an image, and here are a few meta tags with extra information about the document you're reading.

However, as markets drove demand for more and more interactivity - applications in browsers rather then just static documents - browser technologies including HTML evolved beyond the original scope of "marking up text documents". That original design foundation is still there: marking the content structure of a document through HTML tags, though.

The problem is that developers want to cater to demands to build these nice fancy UI experiences that need to be rendered perfectly on various devices. And so, the original intent of HTML goes right out of the window. What's left is an unreadable mess of spaghetti HTML, mangled DOM's with non-sensical auto-generated CSS classes to which one needs compilers and transpilers and entire toolchains as you write your CSS in an entirely abstracted fashion.

When you're building a complex interactive application for the browser. That's just the current state of affairs one will have to accept. Presently, you're still, in essence, using tools that originally never were designed for that purpose.

However, if you're just going to build a simple blog or a site with static content, it pays dividends to think about the structure of your content, consider the semantics of your HTML and the CSS classes you're going to use. Using pure CSS, you could then easily write lean, performant and understandable stylesheets that don't need to be processed by complex toolchains. And you certainly wouldn't need complex frameworks to build a website.

Of course, YMMV, and so there's definitely a market for Tailwind and their ilk. I do think that developers should learn about "golden hammer" syndrome early in their career: while frameworks make your life as a developer easier, they aren't the best choice in all use cases.

From the perspective of a "body shopping" business, it makes sense to standardize the process as much as possible and fall back to a few well known tools and practices with repeatable - and therefore measurable - outcomes. In the same vain, the big trade off here is providing any form sanity/clarity when someone hits the "browse source" button in there browser.

You can use postcss and @apply tag to compose single classes that you can use in your html code like .btn-blue

.btn-blue {

@apply py-2 px-5 flex items-center bg-blue-500 text-white rounded

}

So I don't really see that as a problem. You are supposed to refactor your styles later to be more reusable. What tailwind provides is fast iteration and design. I love that.

I could use sass to do the same.
Yes. You can use tailwind with sass as well though it's not recommended.

Think of tailwind as a framework for all your styling needs while sass is more a functional language to generate CSS for you.

Partially. You'll lose the system Tailwind gives you, which makes it easier to be consistent.
I handcraft that system myself.

It's like buy Ikea furniture and assembling it vs. having your own woodworking shop to handcraft furniture with precise requirements. These frameworks have made me lazy. I think CSS design is pretty much exactly the same as any craftsmanship job - there is so much pleasure from building it from the ground up. No, I still get the knots in the wood out by using reset.css.

Also, I try to not use class selectors as much as possible. HTML looks sterile and spartan with only a handful of span tags or id tags for very specialized targetted changes.

I can see why people use frameworks - its fast and quick. But you lose personality in the outcome.

The exact problem is the 99% of people who DON’T do this and their markup ends up a Frankenstein’s monstrosity. I don’t know if it’s the new crop of front-end “developers” who don’t know the very basics or just hipsters being hipsters and YOLO all the things. Tailwind (IMHO) promotes bad practices and needs to explicitly state that you SHOULD use @apply or a puppy somewhere will die.
I think you can blame compilation time for that. If you only use tailwind utility classes, there is no need for recompilation on every change but with @apply directive and external CSS file, the thing gets compiled every time you make a change.

I wonder if they can bypass compilation in development mode somehow.

Oooorrrr some of us just don't care what you might think are good practices. I find tossing classes is more maintainable than trying to refactor down.
I'm a FE dev with 10 years experience.

I've only started using Tailwind specifically in the last year or so, but I've been using functional CSS for about 6 years.

I don't believe using @apply is a maintainable approach. A better approach is to use view templates. In fact Adam Wathan recommends this way too in this video https://youtu.be/J_7_mnFSLDg

I second this! I have gone full circle myself. From Dreamweaver (have to start somewhere), hand coding, Bootstrap classes and modifying them, then naturally started using utility classes. Finally made the switch to Tailwind (felt like cheating on a lover, because I loved Bootstrap so much). I then went full on utility classes and low and behold, discovered @apply with nested @screen media queries and went right back to writing clean HTML with named CSS classes that use utility classes in a SCSS file. Its so cool to me, I want to tell everyone about it.
Please, tell me more :)
Here is an example off the top of my head, while on iphone:

.card { @apply flex flex-row shadow rounded-md p-4; @screen md { @apply flex-col p-6; } yada... yada... }

then in tailwind config, point the purge path to your html file(s) to purge.

End result is css file with no more and no less than what you need, and in the web inspector you see clean HTML markup and clean CSS declarations.

edit: typo

that's ridiculous, why not just write padding: 2px 5px; display: flex; align-items: center; color: #fff; You are basically just creating a set of attributes that just mimic standard css properties, I find this approach of tailwind absolutely counter productive, and I am surprised that it gets so much popularity.
I think there are two reasons:

- you can copy the classes from html directly into @apply (you need to tinker a bit more to get responsive/hover/etc classes to work, though)

- you work with predefined values, so if you switch color in tailwind.config.js, it's gonna get correct value in the @apply class too.

That's the way I see it

For the second one, couldn’t you get the same effect by just using css variables?
Sure you can and you should, right?

But this way you have to write couple of classes more, couple of variables more. And with Tailwind you just define/change value in the config and you have all the classes generated, so the changes are minimal.

2. which values are you going to ever change in align-center, display-flex and text-color-white, it's not like you will change the display flex to mean display block or align center to mean align start, it will always be the same. Same with color white and 95% of other classes that tailwind uses.
Quick FYI, py-2 is REM based, not pixel. So you know your design will fill properly.
I used to think the same way until i tried it, now i'm completely hooked. it actually makes sense not to extract everything in a "class" simply to separate the presentation out, since that class probably isn't reusable.

plus, it's mostly made to be used with vue/react components which should be small standalone units.

I'm personally looking forward to building websites since using tailwind after a long time

Everybody makes @apply out to be the eventual solution to HTML soup, and a project I'm on uses it heavily—BUT the problem is you're now completely locked into a single framework. You can't ditch Tailwind and still use @apply bg-blue-500. If you used regular CSS properties, design tokens via CSS variables, etc. it would be completely portable. I've switched entire sites from one CSS framework to another and it's challenging but doable with standard approaches. With Tailwind, good luck with that…
Um. The Tailwind compiler produces a plain CSS stylesheet with all the classes you need and none of the ones you don't. You can just dig that out of your build (or wget it from production) and stick it where you normally stick your styles(..!).
That's a single output file compiled down from multiple source files likely using a preprocessor…lol. That's not a solution!
I miss CSS compilers like SCSS/LESS on your vita ;-)

Basically the best way to do CSS I ever worked with was using Bootstrap the LESS way. You could use a sean HTML code with semantic (=speaking) class names and basically do the mapping to bootstrap classes within LESS. This was subsequently compiled to short CSS code. The best of all worlds.

I guess the CSS framework SemanticUI has a similar idea in mind. However, most people use it in the same way as Tailwind. This is web technology as it was done 10+ years ago, when people mixed markup and styling. It's a pity that young folks don't know...

Similar curve. I found my optimal trade-off with tachyons.css.
I did the same thing for a recent side project. Only I still use sass.
The problem I have with pure CSS is it relies on the fact that you and your team are experts at CSS, which is almost never the case. Pure CSS with an unexperienced developer can lead to spaghetti pretty quick. There are always limitations with any approach, including frameworks, but on a team with more than 1 developer and long term maintenance in mind I'd prefer to go with a framework more times than not.
I'm tired of this argument: train your devs for the job you have for them, or if they're not trainable, then find them another position not doing stuff they are incapable of.

We're engineers, let's act like it and know our goddamn stuff, not dumb it down to the LCD.

Blame companies and job titles like 'Full Stack Dev'
This feels like the story of a lot of web tooling: accessibility over all else, especially performance/future maintenance. The fail-fast/move fast and break things culture of some startups bleeds into the aesthetics of tools. Knowledge of tools begins to be confused with skills. Ironically, it burdens new devs heaviest, as they're not able to sort through which concepts/abstractions that tools bring with them are worthwhile, and which are not.

It drove me away from the platform entirely.

(This isn't about Tailwind, I've never used it, so I can't comment on it.)

1. this is a pain.

2. i'll write an abstraction

3. the abstraction is a pain

This is basically exactly what I get out of writing web components. I get the best of every possible dimension I care about. I can write short neat little snippets of code that encapsulates my HTML, CSS and JavaScript in a single place. I can do it just using really simple CSS because it is all scope, I can actually build reusable components, I’m using the native web platform (though I do recommend lit-element as well) and I can do all using modern tooling and JS and all of the benefits that brings.
amen. Not comprompsing layout for responsiveness... things have improved since the 960-grid days. (you've been around!) Amen.
> Incompatibility with IE11, so you can tell the man upstairs "sorry boss it's out of my hands, blame Tailwind"

For those who don't know, IE11 is the last major release of IE. Between a major frontend framework feeling confident dropping IE, and Apple dropping Intel it kind of feels like the end of an era.

I have a Windows 7 machine around that used to run IE 11, but one day it silently updated that to "Edgium", which is great.
This project is really amazing, so much love
IE 11 is no longer supported :(
IE 11 is no longer supported :)
Windows updates are replacing that with Edge on Chromium, even on "unsupported" systems like Windows 7, so here's that.
I've seen some incredible things built with Tailwinds, but it still hasn't clicked for me. It seems like you're learning a completely different language for styling and layout. I also have some gripes with optimization in that the suggested solution to eliminating unused CSS is to use a tool that finds classes in HTML files, which is a pretty rudimentary way to accomplish that. (However, I'm sure in more advanced codebases, particularly JavaScript ones, there's probably a better utility to use.)
What kind of projects do people use Tailwind for? and what's the general role of the person using it? I haven't found a use for it myself as a predominantly front-end dev but I've met a few devs who like it a lot but found that they were generally less comfortable writing plain css without a framework. No shade towards Tailwind intended, just not a paradigm I've gotten on board with yet and trying to understand.
I use tailwind with frontend components. I don't think you're actually supposed to keep the atrocious classes as-is all the way to the end. Or for rapid browser prototyping if I want to get a layout up quickly.

For example, my component uses something like this:

.btn-indigo { @apply py-2 px-4 bg-indigo-500 text-white font-semibold rounded-lg shadow-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-400 focus:ring-opacity-75; }

In the end, I get a <button class="_1aZeRTY"> or similar and that's it, no mess. All of it gets compiled down, and any Tailwind classes I don't use don't make it into the final .js file

Any type of project. Before Tailwind existed, I used a similar system but Tailwind is obviously more complete than what I'd roll in a week. I really don't think of it as a framework since you're still specifying which CSS properties you want to apply, just indirectly via classes.
We use it for a large enterprise webapp. We have a component library that uses react and applies the correct classes to the component there. I came from mostly using styled-components (CSS-in-JS) and tailwind has worked pretty well for us. The benefit of tailwind over css-in-js is primarily one of performance.

The downside is all styling gets shoved into the `className` prop which isn't great. If I had full automonomy to choose the css "framework" I would probably opt for something like `rebass` https://rebassjs.org/

I've been using Linaria recently as a zero-runtime css-in-js library. You get a lot of benefits of css-in-js except it compiles it out of the js and into regular css class names and native css perf. Enjoying it so far as I was always cautious of the unneeded overhead of normal css-in-js solutions.
I don't find plain CSS harder to write. It's a bit more verbose and unintuitive to think about sometimes with long-ass property names, too many ways to do the same thing, a bit too low level etc.

Tailwind simplifies them and make those things more readable as well as visible. Combine that with postcss, you get ton of functionality via plugins.

You can use tailwind in any project. The end result is pretty minimal after purging unlike bootstrap or traditional CSS frameworks. Think of tailwind as high level styling framework that simplifies many common scenarios you tackle with writing few lines of CSS.

You answered your own question, "devs less comfortable writing plain css without a framework"
Nah, I'm very confident with CSS and I prefer functional classes. It's just a far more efficient use of my time to not have to write CSS when there's no need.
I used it for my site here: https://www.listenaddict.com/

I've also used it for other various sites in the past.

Makes it trivial to add / change / design things quickly, which for me as a non-designer, is great. Also, works well to make things look good on mobile/tablet/desktop sizes, light and dark mode.

If you were instead given a specifc design by a designer, would you be able to use Tailwind only or would there be custom CSS mixed in there to finess it to match the designs?
I would 100% be able to use Tailwind only. And in fact, that would be my preference.

In the past, a lot of projects I've seen started with Bootstrap + maybe some theme. Then they slowly add custom stuff that ended up being horribly bloated and impossible to refactor well. With Tailwind, so long as you're using @apply properly, or a decent component system (I prefer Svelte), then it's very easy to keep things in a nicely updated, non-custom design.

That's really cool to hear, that's something I've been a bit confused about since I have to actually dive in to Tailwind. I was unsure how much control you could have from pre-defined classes, but it sounds like it's enough.
Very interesting. As a Svelte user I find Tailwind counter-intuitive, as the CSS is already scoped to the component. I also found the added build step slows down the otherwise snappy dev server. I had purchased Tailwind UI but got a refund after I ended up needing to write custom CSS on top of the Tailwind classes.

I would be interested in your setup (I generally use sapper).

As an aside, can Svelte reactivity add Tailwind classes? For instance class={`color-blue-${someNum}`} or does all that need to be available at build time (I'm assuming the latter).

For whatever reason, the homepage flashes dark mode, switches to light, but the icon stays a sun. I have to click that twice to get to dark mode and then it works as expected.
Thanks, added an issue to my board to check it out!
Using `yarn upgrade tailwindcss` only brought me up to 1.9.6. I had to specify the version to get it to upgrade.
I would assume it's by design. A simple upgrade would potentially break at the very least the colors that you're using (they updated the built-in color palette).
That's understandable, but they didn't clarify that at all in the upgrade instructions, which say to just use "npm install tailwindcss" to upgrade.

edit: And it also broke PostCSS somehow. What a mess!

edit 2: I just noticed the "@latest"

> Extra wide 2XL breakpoint, for designing at 1536px and above

Is it still common for folks to use pixels in their CSS? I moved to em and the rest around 1999 (I think). What is the reason to stick to pixels?

Most people use rem these days, but there are common browser bugs with using rems or ems in media query rules, so in the rules specifically it is common to still specify pixels, even if the rest of your stylesheet uses rems or ems.
Also the magnificent rem (root em) unit.
I think that's referring to screen width. As in, breakpoint for when screen witdth is >= 1536px and as screens use pixels, that is the only unit talking about screens is reasonable in. em/rem/whatever don't make sense in media queries.
px is still easier and more convenient to reason with, plus it's more readable. I use px in my code but I also use a postcss plugin to convert them to rem during build time
Pixels have always had their uses, but I moved from em to pixels even for sizes that would ideally scale with text in order to be able to get things to align to whole vertical pixels (and horizontal ones, when not centered).
I used to like web development some 15 years ago. Ever since frameworks became a thing, I stopped doing any web development. I simply couldn't get myself to setting up a bunch of tools just to process some byzantine file formats to a usable CSS. It was a really great feeling when I discovered Tailwind. Not only building custom, trimmed stylesheets required a single command, everything about using it just clicked. Kudos to people behind it!
Lord, if you tapped out even 5 years ago you still skipped the worst of it. It's relentless, I feel like clean software is hard to find in web development. Web apps are so often written with 5+ different technologies and frameworks all jammed together, and everyone picks a different combination.
TailwindCSS is great but I wish it didn't require custom postcss build pipeline. You can use the prebuilt css file, but it lacks some features.
I don't know if it will suit your workflow but Laravel Mix is pretty easy to use. I use it to process my CSS and JS on Laravel and non-Laravel sites.
The things I love the most about TailwindCSS:

1. After purged the CSS file is really, really small.

2. Hopping into all of my projects and not having to remember new class names.

3. Not having to come up with new class names.

4. Not worrying about making a change in a class and having unintended consequences.

5. Not skipping back and forth between HTML or CSS files.

That said, if you don't dig it, there are plenty of other great frameworks, naming conventions and approaches that people use. Or start from scratch and roll your own.

For frameworks I flirted with InuitCSS for a bit. It's pretty nice and after digging through the code I realized it's not as complex as it first appears.

I also like Andy Bell's approach with Cube CSS.

I’ve been keeping an eye on Tailwind. Over the last few years we’ve switched from old school single css file to css in js, and while that helps with the class spread issues, by lots of other measures it’s inferior. This was solidified for me last week when we rebranded our app and I needed to hack in both new and old code. Editing is js controlled css in the browser is just too painful.

Anyway, couple of weeks back I needed to make a website for a mate and decided I’d give tailwind a spin. My god does it make css fun again. I’m not sure how you look after sprawling styles in a bigger app (though I’m sure I’ll figure something out) but having the right combination of safe css, everything right there and responsive styling locally is a dream. I’m totally sold.

> 5. Not skipping back and forth between HTML or CSS files.

What? I thought the point of this was for use with composable JS components.

You're manually writing and updating attributes like this?!

  class="text-4xl sm:text-6xl lg:text-7xl leading-none font-extrabold tracking-tight text-gray-900 mt-10 mb-8 sm:mt-14 sm:mb-10"
How could you possibly manage this without components? Ctrl-F "lg:text-7xl" and replace?
You make components as usual, but you style with those utility classes. Those utility classes are configurable in one theme file where you can set what "text-4xl" is or how much space "mt-10" is.
Yes, if it's not componentized into a smaller chunk, find and replace works fine. The beauty of Tailwind is though, if you change that, you know exactly what the consequence is since every utility is so highly targeted.

You absolutely do skip between lots of HTML/JSX/VUE files, but that's true of any project. The point of tailwind is to keep you in the view layer of your project and not jumping between more than a browser and one tab in a code editor when building your UI.

> find and replace works fine

It would replace every `.font-extrabold` element on the page.

What if I only want to update my extra bold headlines, not the extra bold subheadings? Global search-and-replace breaks my subheadings.

>> 5. Not skipping back and forth between HTML or CSS files [with Tailwind]

> You absolutely do skip between lots of HTML [with Tailwind]

??

Yep. There's so many global replace situations where the logic completely breaks.
In my experience global replace is much easier across multiple component files rather than multiple CSS files. If I need to do change a font color I do a search and know to change it based on the file/component it's used in. If I had to change the color in css files I'd have to review the class and also track down where that class is in use.
Sometimes I extract to component classes, but in Laravel or Statamc the html element and the classes have already been extracted to a component so there's only one place to make the change anyway. When doing WordPress sites I extract to component classes more often.
You don’t need to be using a JS framework to have components. Pretty much any server-side templating language allows extracting “components” in the form of reusable HTML fragments. And even if you’re serving static HTML, there’s plenty of ways to compile a template into a static file.
Right, components. Not a search-and-replace for every instance of ".color-pink" in your codebase, suggested by the parent.
Lots of good responses already on other ways to abstract, but I'll even go one further and say "sure, why not?"

When are you changing every single instance of "lg:text-7xl"? More often you're probably making a change in one single place in the app, in which case this is incredibly easy, you just make your change where you want. You're not slowed down by digging through layers of abstraction cruft and indirection until you find the right place to make the change.

If you're doing an entire site design refresh, then doing some find and replace isn't really that crazy. For something you do relatively infrequently like this (maybe every couple of months or even every couple of years?) it's not a big deal if it takes a little bit longer. And likely you'll need to look through and test your changes on every page one by one anyway, to make sure you're not breaking anything you didn't mean to. You'll need to do that whether you changed the definition of a css class, or you made a bunch of inline changes, at which point making the actual code edits inline probably isn't even the bottleneck.

But again, that's perhaps a bit extreme of a way to look at it. You will inevitably have some layer of abstraction anyway, something like components or templates or partials, in which to wrap your styles.

> When are you changing every single instance of "lg:text-7xl"

I'm not, I'm changing some 7xl-sized text in multiple places. But I don't want to change every element that is .lg:text-7xl already.

> If you're doing an entire site design refresh

I'm not

> You will inevitably have some layer of abstraction anyway, something like components

I already do, they're in JS, and much more powerful and extensible than HTML attributes.

You could also update the Tailwind config file to define what "text-7xl" is. Default is "4.5rem"
> But I don't want to change every element that is .lg:text-7xl already.
For those complaining about dense HTML using Tailwind, the headline feature of 2.0 should be @apply for everything: https://tailwindcss.com/docs/functions-and-directives#apply

It lets you move all of those excessive class attributes into your CSS, where it realistically belongs. And that makes your CSS look a little more like CSS. But you get guard rails on it by applying a known set of properties to each rule. It's really the best of all worlds.

At that point, what is tailwind offering?
Again, guard rails on those property sets. You are locked into a set of values and they are unlikely to conflict in some odd way.

You can also apply configuration changes globally that might affect multiple properties. If you're changing from px to rem for sizing, you can do that without having to go through your entire code base to update that. Or if you need to tweak a color, it's applied everywhere, including computed values (color variants).

How is that different than Sass with some of the same classes `items-center`, `flex-auto`, `space-x-3` etc?
using @apply adds all of those properties and values into a new css class right? you're adding extra lines to your bundle
> It lets you move all of those excessive class attributes into your CSS, where it realistically belongs

No. Adam said multiple times that he basically added the feature to make onboarding people smoother.

The right way to use Tailwind is to extract components, for example in Vue.

That way you have the markup, behavior, and styling in self-contained in a single file, that can be used anywhere, without leaking any internal implementation details.

Can you help me understand the architecture a bit better? I have some reservations.

If you extract components then you require JS (low lighthouse score, lots of JS processing on slow devices, likely SEO problems) or SSR to render the page and then serve it (high TTFB)

Ideally you would have some kind of build step that can pre-process all the vue components and spit out pre-rendered HTML for all pages but preserve the interactive parts of the component scripts.

> If you extract components then you require JS

Only for interactive components. You can use PHP or a static site generator and create components with no runtime JS at all.

Yeah I suppose if you use a server-side framework you can use a templating engine to create partials for your components and have a single source of truth that way. I was curious to know if there was a way to do it with just Vue + some build step and pre-rendering
Not sure about Vue, but in React the simplest thing you could do is to use ReactDOMServer.renderToStaticMarkup(). You can develop your whole "app" in React and then create a JS-less HTML output. There's also Charge [1], a React static site generator with no client-side JavaScript.

[1] https://github.com/brandonweiss/charge

(comment deleted)

    @apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded;
so @mixin in Sass? @apply in CSS? (being replaced with Shadow Parts)
I think the three levels all have merit. If you don't end up repeating yourself too much, just add the utility classes directly. If you find yourself repeating a bunch of classes together, maybe you can make a semantic class with @apply. If you're repeating a bunch of HTML (and Javascript) along with the CSS, make a component.
> The right way to use Tailwind is to extract components, for example in Vue.

That's not the full story. Using @apply is the only option if you're not using a component based JS framework like Vue or React.

@aply works everywhere. The current documentation highlights this difference; showing both component extraction and using @apply as a failback when you want to go old school.

Sure, you may have to use @apply if you're for example adding Tailwind to an existing project with .css files.

But the right/ideal way to use Tailwind is to use components. That way you get the most dev ex that Tailwind can provide.

Yes but you shouldn't do that really. You should use a view templating system instead to recycle the patterns you spot, e.g. button.tpl would contain the abstraction of classes.

The moment you collapse the classes in to a single class you're back to square one and the reason functional CSS arose be first place.

Adam Wathan promotes this pattern himself in this video.

https://youtu.be/J_7_mnFSLDg

> It lets you move all of those excessive class attributes into your CSS

If only CSS had thought to include such a feature.

Yeah, Tailwind uses postcss to let you use its utility classes with the normal way of doing abstractions in CSS - but it also promotes using Javascript component frameworks where that makes sense.

The utility classes are in themselves great. It's a complete set but it still promotes thinking in design systems.

CSS classes are good, but should be used in moderation. Since you're likely using a component framework anyway, you can often just use the utility classes directly in your components with no loss of clarity and without repeating yourself. But when you do end up repeating yourself in the CSS, you can reach for postcss's @apply and have access to Tailwind's design system. The three levels work extremely well together.

Always have been a huge fan of Tailwind CSS just for the amount of passion that is clearly behind it. The whole utility-only approach is not for me - I prefer a middle ground with utilities and pre-built component classes. Although I am also building a CSS framework, I can only wish them the best of luck. This update looks freaking amazing!

Edit: Removed link to avoid self-promotion.

Tailwind smells like using a style attribute but with properties that are fewer characters. It's fully embracing what everyone said to avoid. What am I missing?
You're likely missing 2 things: 1) you probably haven't delved into Tailwind on a non-trivial project and 2) the nuanced difference is between infinite possibilities (style attribute) vs. discrete, "hard-coded" options (Tailwind classes). Think of strings vs. enum values when describing "types" in an application.
Apologies if this seems snarky but it would be far more useful if you could explain your point rather than a generic condescending "[you] haven't delved into Tailwind on a non-trivial project".
I don't think they were being condescending – there's a lot of material out there on why Tailwind is good, it's easy to find via Google, but nothing beats trying it out.

If you don't want to do that then you could watch some of Adam Wathan's screencasts on YouTube where he uses Tailwind to recreate pages or build new ones.

https://www.youtube.com/c/AdamWathan/videos?view=0&sort=p&fl...

The benefits are "you don't suffer from <some set of problems I've never suffered from, even on large projects>". The cost is cluttered markup and what appears to be impossible reuse.

This smells a lot like every other tech bandwagon. It's the best thing since sliced bread until wide adoption exposes all the flaws and we go back to what proceeded it.

I'm giving myself additional time before I get into it for this exact reason.

Something seems fundamentally off about this library, but I can't pinpoint what.

I dunno. The vibe I get from it is very similar to React. The excitement, the arguments for and against, the focus on some kind of 'separation of concerns' purity that isn't ultimately that convincing.

I waited a while before bothering with React, but based on my positive experience with that particular 'paradigm shift' I gave Tailwind a shot. So far it's been really, really pleasant on a moderately-sized project, so that's hopeful.

I don't see the point in dismissing it, based on all that. We didn't go back from React to jQuery and Backbone, we moved forward from it.

That said, it's fair enough and probably smart to wait and see at this point if you don't have the luxury of experimenting. I totally get that.

That's a very fair comment, but I do sort of agree with the person you're replying to.

Others here have provided reasons why Tailwind is great, and many comments just center around how it's at least not a bad idea.

But for myself, I read a lot of these arguments before and wasn't convinced until I used it in a fairly big project. To some extent it's hard to explain the benefits because once you get past the more 'ideological' issues (separation of concerns, etc.), it's really much more about how it affects the flow of day to day work. I don't think any arguments would've really convinced me, but because of the excitement around here I gave it a shot, and was convinced by seeing how my project grew without many of the usual CSS issues I'd run into (as well as the convenience of just not having to switch to a stylesheet file most of the time).

But I do understand how frustrating a comment like that can be.

Well it is like that, except instead of picking any attribute possible, you're picking from a pre-selected list which have been saved as variables, i.e. utility classes. And it also provides workarounds for the things that inexplicably don't work in inline CSS, like media queries.
What's the problem with style attributes? I would use them instead of regular CSS if I could add pseudo-attributes and make them responsive. Since I can't I use Tailwind where that's possible.
> What's the problem with style attributes? I would use them instead of regular CSS if I could add pseudo-attributes and make them responsive.

Imagine styling a table row. That is one style attribute. Now imagine styling a 100 tables rows. That is style attribute duplicated a 100 times. Think of the amount of unnecessary bandwidth consumed to load that HTML file with 100 duplicate style attributes. Not only does it slow down page load times, it also slows down page render times.

Now if you add selectors to style attributes then it solves the above issue altogether. But, then you are just re-inventing the wheel. Instead of CSS in a separate file you now have the same functionality but all inlined in style attributes.

The render time point is misleading. It can be slower but even on low end devices, CSS is so insanely fast, you would need an HTML source in the tens of MB's range to cause noticeable performance problems. Also, CSS classes do make that even less of a problem. Inline styles are fast enough, and classes are faster by default, so Tailwind wins there.

Page load times are interesting, but again, unless you're loading an insane amount of data from the server, it will never be a real issue.

Some sort of component architecture solves the problem you bring up w/ duplication. You should never be writing the same thing 100x over. JS frameworks all render 100's of the same component with the same attributes and performance is fine for 99% of real use cases.

The downsides for Tailwind all revolve around personal preference and how your team organizes a project. There is no performance hit (unless you ship the entire un-purged CSS file to production, even then, it's minimal).

> you would need an HTML source in the tens of MB's range to cause noticeable performance problems.

What? Do you ever leave the city? It seems like that’s an unsupported use case any many developers minds.

Okay now I'm growing curious, where in hell do you regularly find HTML sources that weigh tens of MBs?
My point is that it's a problem loong before you reach tens of MB, once you leave the dense cell towers and fast hard links found in a city.
That's a good point, but tailwind is primarily suited for component based architectures.

So in this situation you would have a <my-row /> component, which would contain the tailwind classes. This reduces load time as duplication is eliminated, but I'm not sure it would reduce the render time.

Style attributes have very high specificity so they basically preclude using normal CSS files (they would mandate every line include !important)
This is misleading, !important is not required to use inline styles.

They still cascade normally like CSS classes... see this example:

    <div style="color: red">
      <p>red text</p>
      <p>red text</p>
      <p style="color: blue">blue text</p>
    </div>
Ironically, it's actually complex CSS classes and long selectors that produce high specificity, which then requires even more specificity to override and eventually the dreaded !important
The parent is not talking about inheritance. They are talking about specificity.
If an element has a style attribute that sets the color, it will override every single CSS/Style-element style that also sets the color, unless the CSS/Style-element style also includes an !important.
I think one key difference is the way people are developing re-usable components now. Since you only define it once, the benefit of re-usable class names isn't as important as co-locating and scoping your CSS for ease of use. You want as little cascading as possible in that circumstance so again, traditional benefits of classes aren't as compelling.

I use a flavour of BEM naming with an approach I call Contexts and Components to achieve concise, low inheritance CSS and I can see how Tailwind can get you similar benefits and solve for some stuff traditional CSS has a hard time solving within frontend frameworks.

I am still fighting picking it up, but that is the use case I see for it, component driven workflows.

apart from the many points the other repliers raise, you cant write media queries in style attrs. making precise changes to the exact dom elements for responsive design becomes a great deal less a house of cards with tailwind.
The stockholm-syndrome of the few users positively recommending something that changes their development workflow slightly when they were bored of doing things the old ways.
Ah yes, few users. Which is why this post was on top of HN frontpage.

And yes, definitely it's just that it changed the development workflow slightly, not at all that it brings new possibilities and a much better developer experience.

It does. Using inline style attributes is basically a good idea when using a component framework, except for missing features and questionable performance. Tailwind solves that.

There is an influential presentation from, i think, someone on the react team that started the whole CSS-in-JS thing. It just advocated for using inline styles. I can‘t seem to find it.

React and Vue have special handling of the inline style attribute to make it more pleasant to use, so it‘s not been fully discouraged for a while.

I'm a non-designer developer who nonetheless does some frontend work, so with that grain of salt, here's my take:

What everyone said to avoid was actually just wrong. Semantic CSS failed. Tailwind (or utility classes in general) is the best way to implement a reasonably-maintainable and properly-specified version of putting things in the style attribute.

Anyone using the paid Tailwind? Is it worth the price?
Half-OT: Are there good UI toolkits out there based on Tailwind?

I read it is really flexible, but I don't want to start from zero. Most of the time I want to throw some pre-made UI components together and then sprinkel them with customizations when required.

Tailwind UI, by the same authors. But it's a paid product.
Tailwind themselves offer a paid one called TailwindUI[0].

It's still in early access, and I commonly run up against components that are missing and I have to devise a style for myself, but it provides a pretty good starting point for building out a clean looking web app.

[0] https://tailwindui.com/

Pretty nice, thanks!
It's still pretty immature and buggy, so unless you have no problem fixing blocking issues yourself I'll suggest waiting until it becomes more mature.
I don't need it today, but would be nice to have something like that in the future :)
Tailwind is great, my main issue when I used it was that I felt restricted by the limited set of sizes. I wish it was possible to use e.g. "m-7px".
I tend to just extend the config with whatever sizes I feel that I need.
I think they added a bunch in 2.0, so you may want to double check that.
Probably the best invention i added to my tool belt for a long time.

Never was i able to move so quickly to style components in a way that works and you only have to learn one set of keywords. Reminds me a little bit of vim learn once apply everywhere :).

Props to the creators of tailwind !

Incredible work by Adam and team. I'm using Tailwind from beginning and I have so used to it that I'm not even thinking to go back to whatever Bootstrap, Bulma, etc. It's such a joy to work with TW. Once you try to tinker around with Tailwind there is no back, trust me.
that video is quite aggressive.
It's so cringe i was thinking thats joke at first.

I guess that happens when you invest and hire some outside help and sometimes it ends up a bit... unsophisticated?

I am big Tailwind user btw.

Framework author here, yep it is a joke. We literally had the music scored for us by a friend with the goal of making it as outrageous as possible. There's a real opera singer chanting "utility first" in Latin at the end. It's a parody of itself :)
I thought its because of your love of heavy metal!
"Incompatibility with IE11, so you can tell the man upstairs 'sorry boss it's out of my hands, blame Tailwind'..."

I know it's said tongue-in-cheek, but popular frameworks taking this stance is valuable when convincing clients, leaders, authority, etc. to not require IE support. I've consulted on dozens of front-end projects, and showing the stance of "industry leaders" is the most convincing argument.

That's the tail wagging the dog though…

I've got clients whose customers using IE11 represent 1-2% of revenue i.e. $1M+ / year

yes but one of my central arguments [1] is that it is time to explicitly charge customers for IE11 support rather than implicitly have your 99% of customers subsidise support for the 1%

1: https://www.swyx.io/ie11-eol/

these customers are obviously the poorest percentile
Yes, but you're using that argument in the context of a software business rather than a consumer facing retail business
How much could they increase the revenue from the 98-99% by if they dropped IE11 and moved faster, spent less time on supporting old browsers, or embraced new features? It's possible (even likely) that simplifying the code by supporting fewer targets that need additional work would increase the overall profit.
Most likely zero

They're an online retailer and those customers would just go to someone else who's site would work in IE11

People aren't stuck on IE11 out of choice, it's corporate policies and other factors at play

> Internet Explorer represents less than 1% of my work traffic according to Google Analytics. People will sometime spin this away by arguing that 1% of a large number is also a large number. If you have 100 million hits, 1% is 1 million hits! But the flipside is that 99 million hits are not Internet Explorer and are not helped by optimizations aimed at Internet Explorer.

https://blog.carlmjohnson.net/post/2020/time-to-kill-ie11/

1% is 1%. If you can’t find a better way to improve revenue by 1%, you’re in too narrow of a market fit.

(comment deleted)
How many of them are unable to use a new browser? Long back our enterprise app didn't work on IE6, our stance was, "yeah it does not, install Chrome". I don't think we ever lost a deal because of it.
(comment deleted)
At this point even JIRA and Microsoft 365 have dropped support for IE11. The majority of big corporates have either moved to Chrome or are hurriedly doing so.

However, there are presumably old computers in far-off corners of the world that still use IE11. I wonder what will happen there...

They can continue to use IE11 for that one, weird corporate intranet app that nobody likes using anyway, and they can also load a modern browser for everything else the user has to do. Browsers don't exclude each other.
Microsoft, in general, doesn't even really "support" IE as a general purpose browser. They view it as a compatibility platform for old IE-only apps.

Edge is Microsoft's only general purpose browser ATM.

This depends completely on the industry.

Maybe a dev tools startup etc. would accept the Industry Leader argument, but Retail for example would never pass up the revenue opportunity by dropping IE11 support.

I've always appreciated when libraries who drop IE11 support provide polyfills etc., or at least some notes on it, since the library author knows better than anyone which corners are not IE11 compatible.

This eases adoption in these other industries, instead of taking this hard stance which may sound good, but ends up limiting the # of devs who can use the library.

Good news is v1.9 supports IE11 and is pretty damn good already. A lot of the updates here are just default config options for tailwind, that you can add yourself to mimic 2.0
I would have thought that the most convincing argument would be that the company that made the software has deprecated the software and no longer supports it. However, it's not always the user's decision, and they are forced to use IE due to a corporate IT decision to lock down the users from allowing software installs (understandably).

I've used a product for doing webcasts that 90% of the users were on IE11. The training was for nurses using hospital provided computers that are locked down by their IT staff (for good reasons). These poor users are forced to use the default browser that came with the OS. Every single issue that the users had was from someone using IE. Some hospitals finally relented and deployed Chrome for the users doing the webcast.

Has anyone created a react library that is well maintained with the tailwind framework?
twin is a babel macro that supports integrating tw util classes with css-in-js libs like emotion