Last week I just said f it and developed a feature by hand. No Copilot, no agents. Just good old typing and a bit of Intellisense. I ran into a lot of problems with the library I used, slowly but surely I got closer to the result I wanted. In the end my feature worked as expected, I understand the code I wrote and know about all the little quirks the lib has.
And as a added benefit: I feel accomplished and proud of the feature.
By that definition it would be hard to justify anything besides HTML, JS and CSS. That would also exclude TypeScript and every JS Framework there is on earth. That's hard to justify from every angle (development and business wise) imho.
That's not quite the definition they are positing. Many of the classes in Tailwind have near or actual 1:1 mappings to CSS, but with slightly different names or semantics. A better JS analogy might be something like Coffeescript; I remember avoiding it because it felt a bit superfluous and hence not worth the tax (of adding a tool).
With Tailwind, whatever the actual merits, the biggest points of traction (IMHO) are the frankly excellent example sites[1]. You can click through numerous examples, all load quickly and without ads, that give you numerous variations of components, layouts, and even full pages. You can spin up a vanilla HTML or React app and ship good looking pages very quickly, esp. if you are bad at design.
I use Tailwind for a SaaS app because of TailwindUI and I'm pretty happy with it. I also used the Marketing page examples to put together a website[1] pretty quickly.
When the app UI gets more complicated the need for design skills definitely creeps in. But, taking a step back, using a wireframing tool like Balsamiq, and having another look through the component catalog has gotten me pretty far. I'm happy with our ability to ship quickly.
Just an FYI, the logo on the site you posted gets deformed on mobile when there’s not enough space for it and the buttons on the right to live all on the same line.
We use it in production for about a year now. We never had any issues with tailwind or how the markup looks. In the end you put that into meaningful (react) components anyway.
Yeah but that is the easiest example imaginable. The problem is not a button class its the card-left-wrapper-container class that you have to use to style something the right way.
It basically boils down to naming things for me. The author says it's a good thing. I don't think so. Most of the time in plain CSS we have to come up with arbitrary names, that introduce confusion and bugs later on.
Utility classes, while sometimes cumbersome to read, always state their intent.
What's the tailwind equivalent of `card-left-wrapper-container`? I imagine it's 200 characters wide.
Based on the name I'm going to assume that the class is used on container for a layout with cards on the left.
Utility classes don't state their intent they state their literal contents. If the intent is to be a button or be a wrapper-container then that's in a well conceived class name.
> Most of the time in plain CSS we have to come up with arbitrary names, that introduce confusion and bugs later on.
If the names are arbitrary then of course have problems! If you code and made up arbitrary names for functions you'd also have problems. The point of the name is to add clarity and abstract out details I don't need to know. I don't need to know that buttons have a certain padding, margin, etc when I'm placing them on a form. And I don't need to know everywhere they are placed when I style them.
> Based on the name I'm going to assume that the class is used on container for a layout with cards on the left.
That's funny my intention was to name a wrapper around a container inside of card that is usually used on the left side. But of course we had different contexts in mind and a lot of these issues can be sorted out by coding conventions.
The thing is I was never able to wrap my head around the whole separation of concerns thing, when it comes to HTML, CSS and JS. I think that is because I come from a mobile dev background where we always had some kind of markup (or just plain code) which described the elements and how they looked. The structure of the UI and the styling were always co-located.
Coming to the web I was very confused of why you would want to separate both of them. And in my opinion we can see that change not only in TailwindCSS, Tachyon or ChakraUI but also in component based JS frameworks as well. Everything is about colocation these days, which makes it much easier to reason about what is going on in this small, little, pocket of code in my application.
You can create components by aggregating the utility classes in tailwind. In fact, the documentation recommends this approach for production[1]. So if you want your "button" class, you can have your "button" class.
The reason tailwindcss has so many proponents is arguably because of its compositional design, but it's paradoxically not one of the first things people seem to talk about when they're discussing tailwind. They fixate on its utility-first design. I think this does it a significant disservice.
One of the biggest benefits in my opinion is, to communicate the different utility classes to your UI/UX person. By restricting him/her to discrete values for margin, padding, colors, etc. they will not go overboard with there designs and also make the handoff way easier. If you use zeplin for example you can for example define color names in the sketch file and zeplin will show them in their UI. You just click on a text and see "ahh she used text-gray-500".
Much less friction in the workflow.
As for the concerns about messy markup mentioned in some other reply. True that can happen sometimes, but if you use React or Vue, you can encapsulate a lot in components. The markup in the components high up in the tree will look basically the same. And the leaf components should be quite small anyways.
Another really nice benefit to the old way is that you don't have to worry about breaking stuff. When you change bg-gray-200 to bg-gray-300 you can be sure that it only affects the element you have in front of you.
But in the end I think people have to try it out to be able to judge Tailwind.
I haven't worked with the platform for 2 to 3 years. In my old job we had massive problems at the end hence we switched to native (we were an agency).
Problems we had:
* Deploying to devices was painfully slow compared to native stack.
* We all had Macs and the tooling (Visual Studio for Mac/MonoDevelop) was pretty bad compared to Android Studio.
* Wrapping 3rd party native libs was a pain, if not impossible. Especially in a stressful agency environment.
When we heard about the acquisition of Xamarin by Microsoft I was hopeful things would change to the better. But month later they rebranded MonoDevelop and focused on integrating Azure.
Visual Studio for Mac has suffered quite a refactoring after the acquisition, as many of the MonoDevelop internals have been refactored into common libraries shared between Visual Studio and Visual Studio for Mac, one of the reasons why the new plugin infrastructure is based on .NET instead of COM.
And as a added benefit: I feel accomplished and proud of the feature.