Before Tailwind, every web designer I’ve ever worked with invented their own version of this.
Yes, CSS in theory is powerful and has everything necessary to avoid using Tailwind, but in practice CSS has a major flaw: You’re almost required to build a semantic model to get the full power. But this ignores that designers are working with mood and emotion just as much as document structure and information architecture. Capturing these more nebulous concepts as logical semantic rules is very difficult if not impossible. Tailwind just codified what everyone already did: Skip the semantic dance (“Making that text bold would be really cool, but what does it mean to be cool, as a general rule?”) and just create semantic rules like “bold” and “red”.
zarzavat · 5h ago
This is the complete opposite of what good CSS is supposed to be. The class name is supposed to tell you what it is not how it looks like. Anyone remember CSS Zen Garden?
The "good CSS" you're talking about was always the product of convention, and it was never sustainable for big, long-term projects. The CSS Zen Garden showcase only made sense in a world where everyone shared the same document or document structure. Those insane stylesheets depended on the source HTML document's inherent structure, which is the exact opposite of separation of concerns.
Inexperienced developers always underestimated the complexity they were adding to their project by using overly abstract classes and hidden structures between the DOM and the stylesheets. Tailwind (or any reasonable CSS methodology even) recognizes these problems and solves them.
zarzavat · 2h ago
I completely disagree. Look at (old) Reddit which allows for individual styling of each subreddit, or VSCode which allows themes to restyle the editor, as examples of real world products separating style from structure to huge success.
Not everything needs that level of separation, but to say that even basic separation is a problem to be solved by jamming everything into the class list is completely wrong.
jt2190 · 1h ago
> … to say that even basic separation is a problem to be solved by jamming everything into the class list…
Nobody said this.
darepublic · 3h ago
Doesn't react with styles components (or CSS in js) avoid this? I define reusable components, drawing from a shared theme object. But the styles are still css
bapak · 5h ago
Have you read the snippet? You have not, because it's a bunch of Tail-wind noise (very apt name)
Nothing semantic about .bg-white.
AstroBen · 17h ago
I just can't fathom how someone can look at this and think "yeahhhh thats some good clean code". How did tailwind get so popular? Learn plain CSS. It's really good now
const_cast · 2h ago
Code doesn't necessarily need to be clean. We've had, like, two decades of "do clean code" and a lot of the time that mentality is shit. Putting stuff in a separate file and introducing layers and layers of abstractions to keep things "clean" doesn't always make it so. Often, it makes the code more complex, and makes behavior difficult to reason about.
The big problem with Vanilla CSS is that's it's sort of like Perl. It's a read-only language in practice.
Yes, theoretically, you can have perfect semantic CSS classes and use those. In practice, not every button is the same and you'll need slightly different styling in different places.
Yes, we could go in and change the .button class. But who is using the .button class? Where is it used? Nobody knows, and you can't find out. So editing that class is EXTREMELY risky. I have seen many an entire application break because some dev decided to edit CSS. The bigger the application, the bigger the risk.
Where I work, we have 1500 devs. Does anyone know the complete set of usecases a CSS class would have? No. Even if I gave you a month to research it, you would not find out. So you cannot edit CSS classes, it's far too risky.
So, the result is that everyone just tacks on to the end of the CSS. And now, in your clean code world, you have 50 different button classes. Um... whoops.
If you want to compartmentalize, what you can do is use components, in whatever backend/frontend framework you have. You can have the component have their own state and allow users of the component to change parts of it. Then, it doesn't matter how "unclean" the tailwind is - because you'll almost never see it. But if you need to change it, you can, without destroying the entire application. No more 50 button classes, and no more read-only implementations.
Jaygles · 16h ago
I've worked in many different FE codebases with a variety of CSS "strategies".
This sort of thing is objectively ugly and takes a minute to learn. The advantages of this approach I found is two-fold
1. You can be more confident that the changes you are making apply to only the elements you are interested in changing
You are modifying an element directly. Contrast with modifying some class that could be on any number of elements
2. You can change things around quite quickly
Once you're well familiar with your toolset, you know what to reach for to quickly reach a desired end state
AstroBen · 15h ago
This is one of the least elegant ways to scope CSS though.. you may as well just write inline CSS
I like BEM personally. "navbar__item" scopes the styling to the nav item
> Once you're well familiar with your toolset, you know what to reach for to quickly reach a desired end state
This also applies to plain CSS, doesn't it?
The big value add that Tailwind brought isn't their utility classes IMO - it's their philosophy around having a design system of consistent coloring and spacing. I actually borrowed that for my own projects. It taught me to be a lot more diligent about specifying the system upfront. Put it in CSS variables and re-use those
omnimus · 12h ago
You can’t use inline css it’s not at all the same.
Inline css
1. Can’t use media queries (responsive design).
2. Gets you to specificity hell - you loose ability to cascade.
3. Does not follow any system or reuse of values.
4. Values can’t be centrally changed. Utility clases are still classes - when you change class value it changes everywhere where the class is used.
5. Its verbose. Utility classes can have multiple css rules.
Conceptually it might seem that inline css is similar but thats just feeling. Functional css (utility classes) are about composing classes with simpler (one purpose) behaviour together to create complex behaviour.
troupo · 9h ago
> Values can’t be centrally changed.
Or you end up redefining dozens of CSS variables inline :)
elktown · 8h ago
When people complain about CSS being hard I'm not sure what parts of it really? It's rarely explained further too.
As someone that did a lot of CSS like 15 years ago when fullstack was the norm, then just sporadically for various non-public tooling, is that yes, the old ways of trying to position things really sucked and had a lot of hacks and some of those trail-n-error "how-does-this-change-the-elements-position" seems to still apply, but are much rarer now with grids/flex etc. But the structure of CSS itself is very straight-forward to me and has almost always been?
Is what's really going on that when people are trying to use vanilla CSS they go overboard with keeping CSS DRY? Which ofc ends up with an interdependent mess that's becomes increasingly harder to change. Just stop that? Start namespacing and copy pasting? CSS doesn't need to be compact.
iambateman · 15h ago
Agree, and to add…the “component” still needs to exist somewhere in the system for tailwind to make sense.
No one is writing a long paragraph of styles for _every_ button in their app.
nojs · 14h ago
> No one is writing a long paragraph of styles for _every_ button in their app.
Very much not true. LLMs love doing this!
yxhuvud · 12h ago
Yes, many most definitely do just that.
eviks · 13h ago
1. Aren't there good tools that can list all the elements a style would be applied to so that you can pick and change only the ones affecting the element you need?
Levitating · 9h ago
Why not just use the style attribute?
owebmaster · 8h ago
verbosity. Using style, "p-4" becomes padding: calc(var(--spacing)*4);
omnimus · 11h ago
Tailwind goes into crazy extreme so people can copy paste whole complex components and they work. That’s why you can dunk on these verbose examples.
This is not how custom functional css codebase looks. In custom projects you change the system/configuration to fit the project. You create your own utilities for example you wont have “text-lg sm:text-xl font-semibold tracking-tight” but will have class “font-heading-2”. Similarly you will create button/input classes that have you basic styles.
Generally you start with just simple utility classes inside html and go from there and where it make sense or its too complex you separate to more complex class. You end up with short css file that only has these special components and none of the basic stuff.
For most elemets it ends up like “flex justify-center gap-4”. In BEM i have to invent “nav-secondary__header” put it in correct place and hate myself when i need to change it to “flex justify-beween”.
Tailwind popularised functional css but is also aimed at masses/noobs. Somehow some of those concepts also resonated with some experienced users.
adabyron · 1h ago
As an older dev, I think it's a great natural evolution.
We had css, then SASS/LESS/etc, now Tailwind.
In the days of just CSS people would create variables/functions for their CSS in their server side language & have the server side language create the CSS. SASS/LESS allowed us to do that in stylesheets.
Now we have Tailwind (and of course CSS variables). Tailwind (and the code editor plugin devs) have done an amazing job at making a great workflow to handle CSS, especially in component type UI designs.
* Shout out to Foundation and Bootstrap for also helping us get to where we are today. Foundation is underrated in the history.
ricardobeat · 8h ago
> will have class “font-heading-2”
At that point, why not write these in CSS instead? There is little advantage in using the tailwind shorthand classes in your own class definitions.
- You can use plain CSS variables for theming
- You're bringing back the supposed downsides of cascading and shared classes
- simple Gzip compression will achieve similar size reduction as the utility classes
Working on your codebase now requires full knowledge of the Tailwind utilities, layers, directives, pseudo-classes, theming, and all the complexity that comes along with them.
doytch · 7h ago
You’re right - if you only used it for ‘font-heading-2’, you wouldn’t need it.
But like the person you’re responding to said, the ergonomics improve for the majority of cases that are just
‘flex items-center gap-2’.
And yes, you could write it all yourself but Tailwind is a good set of defaults for those classes and minimizes bike-shedding and improves consistency. These are useful things in lots of teams.
I don’t really use Tailwind on smaller personal projects because I love CSS, but in an org of mixed skill levels, it’s pretty damn useful.
(Also, Tailwind uses CSS variables. It had solid support for them in the last major and first class support for it in the current one.)
omnimus · 7h ago
I was unclear. Yes of course you write these classes “font-heading-2” in CSS. Tailwind is essentialy big list of premade classes to dynamically pull from.
I think the functional approach/structure is the interesting part why people like Tailwind. On very small projects i even make “Tailwind by hand” creating those utilites as i go.
> There is little advantage in using the tailwind shorthand classes in your own class definitions.
There are few massive advantages. I dont have to figure out how to name these classes. Other people in the team know them too. And when they see class they dont know they know its something custom probably for a reason.
> You're bringing back the supposed downsides of cascading and shared classes
I never said cascade is bad.
Creating new flat class with 0-1-0 specificity doesn’t break Tailwind. I’ve been through enough of - everything has specific class that’s nested/scoped… from my experience and usecase it’s harder for little benefit except neater html.
> simple Gzip compression will achieve similar size reduction as the utility classes
I meant custom css that you write by hand and have to scroll trough. Not the result pushed to browser. With functional css you manage to do most of the work in html and what doesn’t make sense you can do traditionaly. For example i dont like doing complex hover interactions in Tailwind so the html has all the layout utilities but also custom class that only has this custom interaction behaviour.
> Working on your codebase now requires full knowledge of the Tailwind utilities, layers, directives, pseudo-classes, theming, and all the complexity that comes along with them.
Is knowing Tailwind naming conventions worse than not having any convention at all? My experience is that Tailwind are just classes that are documented. Without it we would have classes that are undocumented.
There are cases where functional css is not that beneficial. Like in long running products which have single file component workflow where css is scoped and html/css live in same file.
But in work i do in small team we just found it to solve many our painpoints.
input_sh · 12h ago
Can I copy some random HTML+CSS snippet from the internet and be sure that it'll look exactly the same in my project and that no existing CSS is going to overwrite it?
I'm never gonna argue learning proper CSS wouldn't be better, but Tailwind is by far the path of least resistance for someone that has no interest in writing frontend for a living. It's like putting legos together, it requires very little thought to get from nothing to a decently looking website.
phartenfeller · 4h ago
It is not the nicest but you will quickly get used to it and productive.
However maintaining huge websites with thousands of thousands of lines of custom CSS will never be easy. And especially if somebody else wrote it.
jtickle · 6h ago
I have seen this sentiment on HN a lot recently. Any good resources for that? I was quite the accomplished web developer 15-20 years ago and want to catch up without having to learn a new library or framework every six months.
I like how tailwind provides scoping automatically. But in projects already having a build system I use css modules. Writing pure CSS is so much nicer but please don't make me manage class names myself.
pjmlp · 15h ago
No idea, thankfully I am doing mostly backend and devops stuff, so I don't need to care.
If I do something myself, I keep using bootstrap, as it is good compromise for those of us not honoured with CSS mastery.
Ironically I have no issues making great looking UIs with native toolkit.
In 5 years the tailwind craziness will be replaced by the next shiny CSS of the month.
pjmlp · 12h ago
Fashion driven development, and magpie developer references come to mind.
troupo · 9h ago
This is objectively good clean code when you develop it.
Because most of those classes are per component.
If you have a single card component defined with these classes, and then repeat it 20 times on the page, then of course the output will look like a giant mess.
> How did tailwind get so popular?
- quick to understand and get started with
- much cleaner for components than the variety of CSS-in-JS libs
- (mostly) do not require fighting CSS with BEM-style atrocities
- come with nice default styles and colors that can be easily changed and extended
> Learn plain CSS. It's really good now
CSS is okay now. We only just got nesting and scoping
emmanueloga_ · 18h ago
In real projects I typically group the classes in a way that makes it easier to read, something like this:
I do this to this day, when I’m writing manual vanilla CSS. I group spacings, fonts, texts, borders etc together so it is easier for me to debug without using too many tools.
Brajeshwar · 16h ago
I have a feeling that Tailwind started with a good intention to be a utility classes CSS framework, akin to “Bourbon on Steroids”, but people began to accept and use their prototype/sample/example codes way better than they had intended, and they ran with it.
I stumbled on Tailwind in 2018 and introduced it to a team looking to revamp a pretty massive project. I remember that the initial proposal I made was to treat it like Bourbon[1] and write classes that build on Tailwind’s utilities. That way, you can still have `.button`, `.button-primary`, and `.button-primary__accent` etc without the cryptic classes in the HTML.
However, after reading Tailwind, the team found it much easier to write the pre-built classes and stack them as they progressed. And it worked; if I don’t care about how the code is written, things were consistent. It reminds me of “Pixel Perfection” before the responsive design era, when things looked as designed in Photoshop and printed for clients during presentations.
We actually ended up adding the custom animation-specific data props to all dialog specific custom elements before the release, so the group-*/dialog is no longer necessary but I forgot to update the code in the post.
I doubt that changes your mind, though.
oleggromov · 20h ago
I came to comment that at least something good happened to the otherwise cursed project... but you made me reconsider.
davidw · 14h ago
It's like Forth and CSS had some kind of hideous offspring.
tomnipotent · 19h ago
Groups are great. It lets a child element activate an effect on a parent element.
This eliminates the need for JS for a wide range of things.
reactordev · 18h ago
But at what cost? If it’s not a CSS builtin, it’s going to use JS - it may not be something you care about, but it will be there. There’s no other way.
mcintyre1994 · 14h ago
Tailwind compiles all the inline stuff to CSS, and this works in plain CSS. It’s just allowing you to define that inline, which you wouldn’t be able to do with inline styles.
It’s the same as how they enable media queries for example, they’re not using JS just plain CSS, but they’re making it available with these inline classes.
lemonberry · 18h ago
I believe it's regular old css. The :has() pseudo class.
It's not even :has, it's just how child selectors in CSS have always worked.
// Not actually needed, here
// for competition
.group {}
// Child selector
.group:hover group\/hover\:bg-black {
background-color: black;
}
// Which is essentially the same as
.group:hover child {
background-color: black;
}
omnimus · 11h ago
Isn’t it funny that in a thread about how Tailwind is bad and people should learn real css… people also think css selectors require JS?
MrJohz · 10h ago
:has doesn't require JS, I think the previous poster was just confused about which selector `group` is equivalent to.
owebmaster · 8h ago
Which is a indication they might not know CSS that well.
MrJohz · 8h ago
Based on other replies, I believe they understood CSS well enough, but didn't understand the exact behaviour of the `group` class in Tailwind. Given neither of your comments seem to have made much sense given the context of the discussion, I wonder if you're just looking for confirmation of things you already 'know'.
EDIT: I'm sorry, I mixed you up with the other user who was replying criticising other people's CSS knowledge.
reactordev · 1h ago
I’m sorry but :has is new. 2023. Forgive this grey beard that built the world you know.
luckylion · 11h ago
That doesn't affect the parent (.group) based on the child though.
MrJohz · 10h ago
No, but `group` doesn't affect the parent in Tailwind. You put `group` in the parent to mark it, and then use the `group/...` syntax to apply different properties to the child, depending on the different states of the parent. This doesn't require `:has`.
I don't think Tailwind has a built-in `:has` tool, but I suspect it would be easy to add one as a custom class.
omnimus · 7h ago
Tailwind has few :has tools but it’s imho terrible. They keep inflating the system to nonsense.
reactordev · 1h ago
This.
luckylion · 8h ago
Oh, I misunderstood the GP then, thanks for clarifying!
omnimus · 11h ago
Atleast in Tailwind that’s what it should do. You hover over card (.group) and some elements inside change.
owebmaster · 8h ago
is it possible to add the hover to the parent without also adding it to the child ?
MrJohz · 7h ago
What do you mean? It's possible to apply attributes to any element in an arbitrary state: `hover:bg-black` would give an element a black background on hover. It's also apparently possible to apply attributes based on whether a state is fulfilled for a child element (i.e. the :has selector). E.g. `has-[:hover]:bg-black` would give an element a black background if any child is hovered.
reactordev · 17h ago
Nice
timeon · 10h ago
Not to mention that for every class here there is also definition in CSS that client needs to download.
monkey_monkey · 21h ago
Yes I agree - it's nice to be able to see exactly what's happening without needing to dive into a rats nest of fragile CSS cascades.
vitaflo · 19h ago
This is literally a rats nest of css cascades.
softwreoutthere · 14h ago
Its atomic though, which is easier for some to reason about. I use devtools.
omnimus · 11h ago
It is not. Utility all classes have basic specificity of 0-1-0. There is no cascade just order of classes that all have same specificity.
skydhash · 21h ago
Why not use the web inspector? That’s usually the quickest way to see which style is applied to an element.
paradox460 · 20h ago
People would rather have to parse out a big dumb list of classes than look at the actual list of what properties affect something, with a clear ability to drill down into them. Its madness, akin to carpenters giving up hammers, preferring to use glue, because they hit their thumb a few times by accident
skydhash · 17h ago
Based on the code I've seen, including written by old me, it seems more like designing the architecture of the CSS styles (and sticking to it) is something people don't like to do. Tailwind is just a tool that is nicer than using the style attribute on the element.
I strongly prefer "button is-primary is-fullwidth" over the long list of tailwind classes.
paradox460 · 16h ago
Same. And all the arguments about using component libraries, like the op, fall flat when you realize components can have scope local styles
gnarbarian · 17h ago
We need a total and complete stop to all front end development until we figure out what the hell is wrong with them.
yoz-y · 16h ago
Some people (I suspect a lot of young and motivated developers) think that UI development should be easy and elegant.
But consider that a UI is 100% state management and side effects (so fundamentally imperative and asynchronous). On top of that it takes about three revisions for any tool to require bespoke display of something (everybody has an opinion). They also bring a layout engine which is best expressed in constraints.
And somehow we are trying to shoehorn all this into a functional paradigm.
pjmlp · 15h ago
Mostly is, with native toolkits, Web should have stayed for hypermedia documents, but here we are.
I have used and programmed enough kinds of UIs, since I got coding into that Timex 2068 in 1986.
Marciplan · 21h ago
kinda feels like jQuery, I like
judah · 1d ago
Looks like it's done using standards-based web components[0]. The page says these components don't require any existing JavaScript framework; because web component support is built-in to the browser.
This has been soooooooo long in the making, i remember playing with webcomponents for personal stuff years ago when i didn't care about compat. Good to see mainstream libraries finally picking it up
12 years I’ve been saying this… 12, damn, years. React graduates look at me crazy. Angular devs say it’s not needed anyway. Svelte bros say get bent. I’m so happy that someone is paying attention.
You don’t need a shadow dom, you don’t need rerendering of everything when a simple value changes. You simply need web components and scoped js/ts with vite or whatever rollup you use.
JoeyJoJoJr · 10h ago
Can you point to any example projects or a todo list app that shows how modern web component can be utilized.
reactordev · 1h ago
Sure
class App extends HTMLDivElement {}
customElements.define(“main-app”, App)
<body><main-app/></body>
I remember toying with Polymer circa 2014, for some reason the word "transclusion" jumps into my mind, I remember being excited about it at the time. I barely remember what it means today though.
8n4vidtmkvmk · 16h ago
Polymer still haunts me to this day. It never made sense. It was literally designed to be deprecated. It's a big nasty polyfill for web components and it had/has a huge perf overhead. Not to mention it's ergonomics are just bad.
julik · 22h ago
I believe "transclusion" was the Angular 1.x vernacular for "slots", but don't quote me on that ;-)
shortrounddev2 · 1d ago
We use web components at the hook for my company's advertising code but I've found them pretty thoroughly disappointing, personally. They make it simple to trigger code execution but their API isn't really that good
spankalee · 23h ago
The whole point is to make it simple to trigger code and to be interoperable. Then you write whatever code you want to implement the component.
Web components are not analogous to frameworks because frameworks tightly couple the component interface and lifecycle hooks with the component implementations. Those are properly decoupled in web components and you bring whatever rendering layer you prefer.
combyn8tor · 20h ago
This is great. Last time I looked into this UI component world I was surprised the popular UI libraries weren't all 'headless' at their base. Web components have been around a long time now. What was stopping this approach?
There are so many framework specific libraries like shadcn, and the community set about building half finished conversions for different frameworks like Vue, which are always several iterations behind and don't really work properly. They have their own version of the docs and it all relies on a specific version of Vue and a specific version of Tailwind and whatever else. It's an abomination.
Start with headless UI as a base and then build wrappers for specific frameworks if you really feel the need. But the wrappers should be syntax sugar only and linked directly to the base library.
I'm sure it's all more complicated than that but a man can dream.
chrismorgan · 16h ago
Put simply: if you’re using something like React, Vue, Svelte, whatever, then Web Components are strict overhead in terms of bundle size and runtime overhead. And when there’s impedance mismatch between the two worlds, which I hear is particularly common in React (can’t attest it personally, I don’t use React), you have to compromise on functionality or ergonomics, or else do fancier bindings, at which point why even bother with Web Components?
It will also commonly not play nicely with some more advanced aspects of the frameworks, like server-side rendering will probably suffer (depending on how exactly things are done).
In a world where React is dominant and you’re wanting to use React yourself, targeting Web Components just doesn’t make sense.
Then “headless” makes it worse. The more comprehensive implementations have a lot of overhead.
owebmaster · 8h ago
> In a world where React is dominant and you’re wanting to use React yourself, targeting Web Components just doesn’t make sense.
Just a reminder that jQuery was once dominant, too.
combyn8tor · 14h ago
Here's my put simply:
We've got some UI components built with html, CSS and JavaScript. They use web standards.
We want to add them into web frameworks that are built in JavaScript. They are built for html, CSS and JavaScript.
No need to overcomplicate things.
And for a universal component library I'll happily accept 7kb extra overhead in my 4mb React slop website
abtinf · 1d ago
The world would be a significantly better place if someone could throw a small mountain of money at the Tailwind folks so that they can stop worrying about money and simply make the full tailwind experience freely available. There are so many lost opportunities for deep integration with other projects.
Kind of like how Jeff Bezos threw a bunch of money at 37signals at some insane valuation, which helped them completely avoid the VC trap.
abxyz · 1d ago
Worried about money? They are already rich beyond their wildest dreams. They are, reasonably, excited about growing and expanding and building a company that does much more, but that is not driven by a need for money, it is driven by their ambition.
edit: I can’t speak for Adam etc., this is just my impression. My impression is that they want to build a business of which tailwind (the open source project) is one part. I think that regardless of money in the bank they would want to have revenue generating projects. Laravel is a good comparable.
_betty_ · 22h ago
interesting, i had just watched Primeagens Standup with Adam and got the impression they don't do well for money, but a quick google came up with a bunch of posts from Adam himself disclosing some fairly impressive numbers.
No idea if he still does ok from it, but he certainly did at one stage.
adamwathan · 18h ago
We are still healthy and profitable but revenue is down about 60% from peak, and continuing to trend down (I think mostly due to AI and open-source alternatives to the things we've historically charged for.)
So things are fine but we do need to reverse the trend which is why we are pretty focused on the commercial side of things right now.
We started a corporate sponsors/partner program recently, and I'm hoping that will earn us enough funding to focus more on the free/open-source stuff, since that's where we create the most value for the world anyways. Fingers crossed!
stevoski · 2h ago
Adam, the Tailwind corporate sponsorship program is a great example of how to do it. I hope other notable open source projects learn from you.
subarctic · 22h ago
Fwiw I feel like their components are something I'd be less likely to want to pay for now that you can generate tailwind components so easily with ai. I guess now that I think of it I actually paid for them back when it was called Tailwind UI, but instead of using them I'm just telling claude to generate a UI for me, which has the advantage that there's no licensing issues. It'll be interesting to see how their business does going forward
nikkwong · 21h ago
How has shipping high quality products using AI generated tailwind components actually been working for you? I think the problem that I and many others have/had, is that it can certainly build a few components that look good in isolation, but it doesn’t do a good job at maintaining a cohesive theme/idea across many different page sections/components etc. I built blendful [0] to solve this, and sort of lost interest when LLMs became increasingly capable. However, seeing them not making any gains, really, on visual cohesion between sections and components provoked enough excitement to continue working on it this year.
We will see how long it takes for LLMs to make headway in this area specifically.
I'm not there yet, but I wouldn't say I've ever shipped anything with a high quality cohesive frontend. In general though, don't people usually ditch these component libraries and write their own set of components once they reach a certain point?
agloe_dreams · 1d ago
> Kind of like how Jeff Bezos threw a bunch of money at 37signals
Honestly, I kinda feel like 37Signals would have been better off with the founders having someone to report to...
moooo99 · 23h ago
How so? As an outsider, they appear to be a healthy business ans a good employer to work for?
richardlblair · 23h ago
Didn't see today's DHH rant about talk therapy?
trevorhinesley · 23h ago
Where he encouraged people to lean into intentionality and finding purpose rather than using therapy as a replacement?
I have a diagnosed anxiety disorder and I’ve benefited GREATLY from talk therapy in numerous ways. I’m an advocate for therapy. I simultaneously stand behind his post as a healthy nudge for many.
jw1224 · 1d ago
The “full Tailwind experience” is already freely available. What “lost opportunities for deep integration” is a frontend CSS framework missing?
Tailwind Plus (the commercial product) is like buying an off-the-shelf template. It’s just a collection of themes and pre-built components — useful for devs who want to get started quickly on a project, but it’s cookie-cutter and can easily be replicated by anyone with Tailwind itself.
vinnymac · 1d ago
There are devs who think the currently available HTML elements are all we needed. But there are many more that believe we are missing primitives that Tailwind (and others) is attempting to solve for.
> It’s just a collection of themes and pre-built components
All reusable web components could be described as an optionally themed pre-built component. That's kind of the point.
kyriakos · 12h ago
I no longer see value in prebuilt templates since LLMs can put things together sufficiently well for prototyping. Even when using templates before you still needed to customise them. Feels like we are going through a transition period.
brailsafe · 1d ago
> There are so many lost opportunities for deep integration with other projects.
What kind of integrations are you thinking of?
bluetidepro · 23h ago
I think you are confused? Tailwind is already free and open source? These are just components they sale that are pre-made to save you time. It doesn’t take away much at all from the full experience?
devmor · 22h ago
From the linked article:
> To pull this off, we built @tailwindplus/elements — a library we're releasing exclusively for Tailwind Plus customers.
This means if you want to use the Tailwind UI components without a Javascript framework, you have to build them all yourself, or pay.
lvl155 · 8h ago
Dude, a lot of devs bought their products during pandemic. They had a great launch if I remember correctly.
ayhanfuat · 1d ago
I wouldn’t get too excited about it to be honest. At one time they were also supporting Vue but it is now basically abandoned.
spankalee · 23h ago
This is Vue support.
With so many frameworks out there it's infeasible to build custom wrappers for them all. With web components they can build once, and work everywhere. It's only up to the frameworks to make sure they have great web components support (which just means great HTML support).
skrebbel · 23h ago
Vue has great web component support. Even React 19 (finally!) does.
Web components are a mess but this is a great application of them: shipping reusable components that work in all frameworks. It's the one and only killer application of web components.
Frankly I'm surprised they're marketing this as "for vanilla javascript" and not as a "now supports all frameworks" type positioning.
ayhanfuat · 22h ago
That’s not really the point. Tailwind UI depends on Headless UI. Headless UI had both Vue and React packages. The Vue package was abandoned. Many are in the process of finding workarounds for the issues or moving to another library. This new shiny thing can be used in Vue, sure. I know better now to not build anything on top of it though.
dawnerd · 23h ago
They also had a figma design library that went away. Kinda silly if you want to get designers on the same page.
GenerWork · 23h ago
At this point, the new crop of AI enhanced design tools are basically skipping vector based design and jumping right to code. A lot of them are using ShadCN/UI which is styled using Tailwind, so it's more like designers are somewhat unknowingly getting onto the same page as Tailwind.
croes · 23h ago
It’s tailwindcss for a reason
bikeshaving · 1d ago
This is a exciting use-case for custom elements, and probably how tailwind should have been implemented from the start, but it’s hilariously a paid feature?! (https://tailwindcss.com/plus#pricing) Intuitively, I’d expect the custom elements to be free and the framework integrations to cost money.
gavinray · 1d ago
Tailwind Plus is a paid collection of UI components and templates.
TailwindCSS itself is meant to be nothing more than a styling tool, like Bootstrap...
conradfr · 21h ago
Bootstrap has javascript components.
dzonga · 9h ago
different business models. bootstrap was made by twitter which was making money in it's way. while tailwind their monetary model is selling components.
for me the only thing I wish bootstrap had was the money color options tailwind has e.g bg-indigo-400 etc
bikeshaving · 1d ago
The title of the blog post mentions Tailwind Plus so I’m assuming it’s a paid feature. The ambiguity is probably intentional.
Alupis · 1d ago
It's not very expensive, all things considered. $299 for a single-user perpetual license (includes all future updates too) or about $1k for a team license[1].
If it saves you a bunch of time writing and maintaining the sort of components they are showing off, probably worth it?
Yeah I strongly emphasise with them getting their money - the only problem with headless components being behind a paid license is that you cannot build a design system on top of them and open source it.
whatever1 · 1d ago
ChatGPT can just steal it for me!
bikeshaving · 1d ago
Listen, I’m not against the Tailwind team getting their bag – they worked hard and created an amazing open source library. I just don’t think it’s in the interest of either users or maintainers to put vanilla JavaScript support behind a paywall.
Edit: apparently all framework integrations and the whole library and functionality is behind the same paywall? And regular tailwind is just the css classes/build process that I used to know? Do people not understand how casual readers might be confused about all this?
yieldcrv · 1d ago
You can use vanilla tailwind with vanilla JavaScript
monkey_monkey · 1d ago
The entire component library is behind a paywall...are you saying they should be giving away the vanilla JS version?
adamwathan · 18h ago
Thanks! It's a paid feature because we just spent around $250,000 developing the library. Couldn't have built it if we were just going to give it away and maintain it forever for free, our engineers are talented people and deservingly well-paid.
It's funny because they're unintuitive to their end users. However, that is deliberate - they are looking for a decision point that comes after, but not too long after, devs have heavily invested in the product.
hbn · 1d ago
Yeah this seems like an odd thing to paywall. In the web dev world where everything is free, it's a pretty crazy ask to ask people to tie themselves to a UI framework where I guess you're forever paying a subscription just to continue using the framework?
It's like putting if postgres expected you to pay them a monthly fee.
edit: I see now their pricing is one-time perpetual access. Still, I'm genuinely curious how well this model works.
abtinf · 1d ago
> I guess you're forever paying a subscription just to continue using the framework
It's a one-time fee for unlimited use and lifetime updates, not a subscription.
bitbasher · 23h ago
Seems like this is a move to remove alpinejs from the custom block elements in tailwindcss plus? I don't see alpinejs in the code snippets anymore.
edit:
Confirmed, they removed alpine from their copy/pastable code. Now you see:
<!-- Include this script tag or install `@tailwindplus/elements` via npm: -->
This sucks because I have been using alpine and now I can't copy paste the examples ~_~
Imustaskforhelp · 1d ago
This is the only feature I genuinely want available for tailwind free users too. Sounds really interesting and I can't even try this? That's a shame.
But I understand that funding open source is never easy & I still appreciate tailwind from the bottom of my heart simply because some might hate it for what it is, but I appreciate that I have options to being with (daisy,tailwind etc.)
If anyone who has ever contributed to open source is reading this. Thanks. I am a real frugal person but one day, I want to earn enough money that I can donate to you guys without hesitation and be an open source contributor too.
rafram · 1d ago
> You can even build something as sophisticated as a custom command palette with Elements
Well, yeah, because they added an `<el-command-palette>` that specifically does that.
dandano · 10h ago
Tailwind plus has saved me 100s of hours for my rails based development. JS was the only thing missing for me, so stoked for this.
joduplessis · 14h ago
I've been working with TW more lately and I must admit - there is a convenience factor there that is really nice - and it abstracts a lot of the finicky design system thinking.
But, if you're building any long-term product, investing in your own design system + component library will put many many more miles on the board in terms of DX, flexibility, aesthethic language, dependency footprint, etc.
jlukic · 20h ago
Working on a new version of semantic ui for authoring ui with web components and signals based reactivity without a compilation step.
I still can't justify using Tailwind. It's not that I don't like it, but I find CSS does everything I need and more, and I do some pretty complex styling and animations in CSS.
I just find that at some point, Tailwind gets in the way and I revert back to plain CSS. TW invariably then just becomes another style src in the HTML.
megaman821 · 22h ago
I am not a Tailwind user but I am a big fan of these "headless" web components. I have been using home-grown web components for tabs, modals, drawers, dropdown, tooltips, toasts and selects they implement functionality and accessibility with minimal styling. I use them across different projects and different solutions (Django templates, Vue, React, vanilla HTML) without any problems.
pzo · 12h ago
Wish there was something like that for React Native or even Lynx. Then I would happily pay for plus bundle.
mediumsmart · 8h ago
Vanilla HTML support is in the pipeline, hang in there.
paranoidxprod · 1d ago
Would love to know how they went about implementing these. I always find custom elements interesting. I know the guys over at data-star.dev used one to implement their inspector element, but unfortunately that is also behind pro.
I know Lit is used a lot but I’m always looking for new approaches.
WorldMaker · 1d ago
Since you are asking about other approaches, I've been doing some interesting and simple custom elements with my Knockout-inspired view engine [0]. I built an open source MPA application with a bunch of them [1]. I even gave a brief presentation on it [2] (each PR starting with #2 is a "slide"; I presented it in a "Presentation" profile for VS Code opening the numbered files in order, with the Live Preview extension side-by-side with a simple git alias to jump to "slide" merge commit based on PR number; I thought it went well to show off Developer Experience).
My biggest advice appears to be: remember that the Shadow DOM is optional.
They don’t mention whether the custom elements are using shadow root and whether it’s open or closed mode.
That has implications for event handling and style encapsulation.
owebmaster · 1d ago
it is easy to check using inspect. They are not using shadowDOM which is great.
paranoidxprod · 1d ago
I mean they mention the built in browser features they use, but make no mention of the actual authoring of the components unless I’m missing something. I’m curious if they’re leaning on existing frameworks for authoring web components or if they’re implementing them from scratch.
gnarbarian · 17h ago
when a front end developer encounters a minor inconvenience he can't wait to avoid it by creating a series of larger ones.
mmcclure · 19h ago
I love seeing a mainstream/popular project embracing web components. We've been working on a web components project for media players[1] for a while for the same reasons:
Instead of being coupled to a specific JavaScript framework, these custom elements work anywhere you can use a <script> tag
But...React is still the elephant in the room here. Maybe TW is just in a different world if they're truly just anticipating folks using this via a `<script>` tag, but if not, very curious how they're going to deal with some of the web component (WC) stuff we've dealt with, like:
- Despite signals/promises, React 19 didn't add full support for WC. React uses a diff algorithm for reconciliation. There are some rough edges for any "complex value" cases in the incomplete solution for 19's WC support with client vs server side rendering. This results in us being required to use 'use client' for parts of our component architectures, meaning WC providers aren't able to take full advantage of SSR.
- WCs are async loading, which in combination with React can have a negative impact on performance for things like core web vitals (and the dreaded cumulative layout shift).
- WCs are just different from React patterns. Each WC creates a DOM element, but React components don't have to, which just inherently means different shapes of code.
- React focus management libraries don't play nice with WCs. We've talked to multiple devs/companies that were excited about/using WCs that backed out because of cross-ecosystem complexities like this.
- React Native is, uh....a whole thing.
On a somewhat separate note...one of my complaints about TW historically has been that it feels like "just classes" (great!), yet requires a build step (oh...). I'm a little confused to see them leaning into `<script>` tags given that, so am I just missing something?
A love letter their rails users indeed. Congratulations to the tailwind team for shipping this! Disclosure
piyiotisk · 1d ago
I would like to know how they find it in comparison to a framework like react
gedy · 1d ago
Tailwind is fine, but I do find it humorous that they discourage wrapping up tw classes into a component class ala Bootstrap, but they wrap html up like this:
(I realize you have full control over looks with TW, but Bootstrap and others have utility classes too for the common stuff.)
DimmieMan · 19h ago
The wordiness is a common complaint but TBH it's a minor issue, I do have a growing problem with using tailwind that's hidden just behind that superficial complaint though.
px-3, py-2, bg-red-400 etc. are everywhere in tailwind code and they become more or less undocumented conventions. Technically you can configure them, but practically without unintended side effects on an existing project? And if you make extensive config changes, have you just locked yourself out of the ecosystem?
I don't use bootstrap, but from a brief look at the documentation it seems much more reasonable to diverge from defaults. Looking at themes (https://themes.getbootstrap.com/) it seems more flexible than an average tailwind setup.
which is even better than what Bootstrap provides since you get type safety for component props (and more opportunities for customization than what Bootstrap allows)
notpushkin · 1d ago
Type safety is good, but the class soup inside the components is just abysmal. And honestly, more often than not I see it spilling out of the components and onto the page layouts.
Design tokens are the one Tailwind feature I genuinely like. Everything else – kill it with fire. Just use whatever scoped CSS your stack does (<style> in Svelte/Vue, Emotion in React?).
bernawil · 23h ago
class soup is what tailwind is. It's terrible because is just abbreviations of css attributes which you still need to know because you'll inevitably fiddle around devtools trying things out.
The only "smart" thing about it is leaning strongly on using rem.
how can it spill out onto the page? it's inline css. The (rare) inline selectors target only descendants.
Truth is that it's winning over because it works best with LLMs. Inline soup works better than looking for styling on different files in the context of the project, so here we are.
notpushkin · 17h ago
> how can it spill out onto the page? it's inline css.
Because people are lazy and don’t make a component for everything. And some people are even lazier and don’t make UI components at all. I’ve seen a project where there was a Button component and that’s it. Well, that was vibe coded probably so makes sense.
> Inline soup works better than looking for styling on different files in the context of the project, so here we are.
Only if you have a separate .css. If you do UI components with [insert your favourite CSS-in-JS solution], it stays in the same file. Maybe the proximity to markup within the file is important?
But no, Tailwind has been rising in popularity long before LLMs came along.
bernawil · 2h ago
[I'm assuming styled-components was the preferred css-in-js solution until recently]
> If you do UI components with [insert your favourite CSS-in-JS solution], it stays in the same file.
I mean you can but "best practice" all around has been to put them separate and that's reflected in the majority of github repos in the training data of the LLMs.
> Maybe the proximity to markup within the file is important?
that's my assumption, yes. Seems to me LLMs work best when they output the relevant tokens right there with the markup instead of referencing some previous tokens even if relatively close.
styled components was the recommended solution in popular UI libraries like React MUI up until 2023 when chatgpt came out. Tailwind REALLY blew up with LLMs.
victorbjorklund · 22h ago
Finally!
vFunct · 1d ago
Would this work with DaisyUI components?
nop_slide · 23h ago
I don't see why not. I imagine the css classes in the examples are simply for styling, as long as you nest and structure the custom elements themselves correctly I imagine you should be able to style them as you wish.
I have a daisyui project too, so I might try this later.
nodesocket · 1d ago
I use DaisyUI in combination with Tailwind but it certainly has some JS backing.
Yes, CSS in theory is powerful and has everything necessary to avoid using Tailwind, but in practice CSS has a major flaw: You’re almost required to build a semantic model to get the full power. But this ignores that designers are working with mood and emotion just as much as document structure and information architecture. Capturing these more nebulous concepts as logical semantic rules is very difficult if not impossible. Tailwind just codified what everyone already did: Skip the semantic dance (“Making that text bold would be really cool, but what does it mean to be cool, as a general rule?”) and just create semantic rules like “bold” and “red”.
The "good CSS" you're talking about was always the product of convention, and it was never sustainable for big, long-term projects. The CSS Zen Garden showcase only made sense in a world where everyone shared the same document or document structure. Those insane stylesheets depended on the source HTML document's inherent structure, which is the exact opposite of separation of concerns.
Inexperienced developers always underestimated the complexity they were adding to their project by using overly abstract classes and hidden structures between the DOM and the stylesheets. Tailwind (or any reasonable CSS methodology even) recognizes these problems and solves them.
Not everything needs that level of separation, but to say that even basic separation is a problem to be solved by jamming everything into the class list is completely wrong.
Nobody said this.
Nothing semantic about .bg-white.
The big problem with Vanilla CSS is that's it's sort of like Perl. It's a read-only language in practice.
Yes, theoretically, you can have perfect semantic CSS classes and use those. In practice, not every button is the same and you'll need slightly different styling in different places.
Yes, we could go in and change the .button class. But who is using the .button class? Where is it used? Nobody knows, and you can't find out. So editing that class is EXTREMELY risky. I have seen many an entire application break because some dev decided to edit CSS. The bigger the application, the bigger the risk.
Where I work, we have 1500 devs. Does anyone know the complete set of usecases a CSS class would have? No. Even if I gave you a month to research it, you would not find out. So you cannot edit CSS classes, it's far too risky.
So, the result is that everyone just tacks on to the end of the CSS. And now, in your clean code world, you have 50 different button classes. Um... whoops.
If you want to compartmentalize, what you can do is use components, in whatever backend/frontend framework you have. You can have the component have their own state and allow users of the component to change parts of it. Then, it doesn't matter how "unclean" the tailwind is - because you'll almost never see it. But if you need to change it, you can, without destroying the entire application. No more 50 button classes, and no more read-only implementations.
This sort of thing is objectively ugly and takes a minute to learn. The advantages of this approach I found is two-fold
1. You can be more confident that the changes you are making apply to only the elements you are interested in changing
You are modifying an element directly. Contrast with modifying some class that could be on any number of elements
2. You can change things around quite quickly
Once you're well familiar with your toolset, you know what to reach for to quickly reach a desired end state
I like BEM personally. "navbar__item" scopes the styling to the nav item
> Once you're well familiar with your toolset, you know what to reach for to quickly reach a desired end state
This also applies to plain CSS, doesn't it?
The big value add that Tailwind brought isn't their utility classes IMO - it's their philosophy around having a design system of consistent coloring and spacing. I actually borrowed that for my own projects. It taught me to be a lot more diligent about specifying the system upfront. Put it in CSS variables and re-use those
Inline css
1. Can’t use media queries (responsive design).
2. Gets you to specificity hell - you loose ability to cascade.
3. Does not follow any system or reuse of values.
4. Values can’t be centrally changed. Utility clases are still classes - when you change class value it changes everywhere where the class is used.
5. Its verbose. Utility classes can have multiple css rules.
Conceptually it might seem that inline css is similar but thats just feeling. Functional css (utility classes) are about composing classes with simpler (one purpose) behaviour together to create complex behaviour.
Or you end up redefining dozens of CSS variables inline :)
As someone that did a lot of CSS like 15 years ago when fullstack was the norm, then just sporadically for various non-public tooling, is that yes, the old ways of trying to position things really sucked and had a lot of hacks and some of those trail-n-error "how-does-this-change-the-elements-position" seems to still apply, but are much rarer now with grids/flex etc. But the structure of CSS itself is very straight-forward to me and has almost always been?
Is what's really going on that when people are trying to use vanilla CSS they go overboard with keeping CSS DRY? Which ofc ends up with an interdependent mess that's becomes increasingly harder to change. Just stop that? Start namespacing and copy pasting? CSS doesn't need to be compact.
No one is writing a long paragraph of styles for _every_ button in their app.
Very much not true. LLMs love doing this!
This is not how custom functional css codebase looks. In custom projects you change the system/configuration to fit the project. You create your own utilities for example you wont have “text-lg sm:text-xl font-semibold tracking-tight” but will have class “font-heading-2”. Similarly you will create button/input classes that have you basic styles.
Generally you start with just simple utility classes inside html and go from there and where it make sense or its too complex you separate to more complex class. You end up with short css file that only has these special components and none of the basic stuff.
For most elemets it ends up like “flex justify-center gap-4”. In BEM i have to invent “nav-secondary__header” put it in correct place and hate myself when i need to change it to “flex justify-beween”.
Tailwind popularised functional css but is also aimed at masses/noobs. Somehow some of those concepts also resonated with some experienced users.
We had css, then SASS/LESS/etc, now Tailwind.
In the days of just CSS people would create variables/functions for their CSS in their server side language & have the server side language create the CSS. SASS/LESS allowed us to do that in stylesheets.
Now we have Tailwind (and of course CSS variables). Tailwind (and the code editor plugin devs) have done an amazing job at making a great workflow to handle CSS, especially in component type UI designs.
* Shout out to Foundation and Bootstrap for also helping us get to where we are today. Foundation is underrated in the history.
At that point, why not write these in CSS instead? There is little advantage in using the tailwind shorthand classes in your own class definitions.
- You can use plain CSS variables for theming
- You're bringing back the supposed downsides of cascading and shared classes
- simple Gzip compression will achieve similar size reduction as the utility classes
Working on your codebase now requires full knowledge of the Tailwind utilities, layers, directives, pseudo-classes, theming, and all the complexity that comes along with them.
But like the person you’re responding to said, the ergonomics improve for the majority of cases that are just ‘flex items-center gap-2’.
And yes, you could write it all yourself but Tailwind is a good set of defaults for those classes and minimizes bike-shedding and improves consistency. These are useful things in lots of teams.
I don’t really use Tailwind on smaller personal projects because I love CSS, but in an org of mixed skill levels, it’s pretty damn useful.
(Also, Tailwind uses CSS variables. It had solid support for them in the last major and first class support for it in the current one.)
> There is little advantage in using the tailwind shorthand classes in your own class definitions.
There are few massive advantages. I dont have to figure out how to name these classes. Other people in the team know them too. And when they see class they dont know they know its something custom probably for a reason.
> You're bringing back the supposed downsides of cascading and shared classes
I never said cascade is bad. Creating new flat class with 0-1-0 specificity doesn’t break Tailwind. I’ve been through enough of - everything has specific class that’s nested/scoped… from my experience and usecase it’s harder for little benefit except neater html.
> simple Gzip compression will achieve similar size reduction as the utility classes
I meant custom css that you write by hand and have to scroll trough. Not the result pushed to browser. With functional css you manage to do most of the work in html and what doesn’t make sense you can do traditionaly. For example i dont like doing complex hover interactions in Tailwind so the html has all the layout utilities but also custom class that only has this custom interaction behaviour.
> Working on your codebase now requires full knowledge of the Tailwind utilities, layers, directives, pseudo-classes, theming, and all the complexity that comes along with them.
Is knowing Tailwind naming conventions worse than not having any convention at all? My experience is that Tailwind are just classes that are documented. Without it we would have classes that are undocumented.
There are cases where functional css is not that beneficial. Like in long running products which have single file component workflow where css is scoped and html/css live in same file. But in work i do in small team we just found it to solve many our painpoints.
I'm never gonna argue learning proper CSS wouldn't be better, but Tailwind is by far the path of least resistance for someone that has no interest in writing frontend for a living. It's like putting legos together, it requires very little thought to get from nothing to a decently looking website.
If I do something myself, I keep using bootstrap, as it is good compromise for those of us not honoured with CSS mastery.
Ironically I have no issues making great looking UIs with native toolkit.
In 5 years the tailwind craziness will be replaced by the next shiny CSS of the month.
Because most of those classes are per component.
If you have a single card component defined with these classes, and then repeat it 20 times on the page, then of course the output will look like a giant mess.
> How did tailwind get so popular?
- quick to understand and get started with
- much cleaner for components than the variety of CSS-in-JS libs
- (mostly) do not require fighting CSS with BEM-style atrocities
- come with nice default styles and colors that can be easily changed and extended
> Learn plain CSS. It's really good now
CSS is okay now. We only just got nesting and scoping
I stumbled on Tailwind in 2018 and introduced it to a team looking to revamp a pretty massive project. I remember that the initial proposal I made was to treat it like Bourbon[1] and write classes that build on Tailwind’s utilities. That way, you can still have `.button`, `.button-primary`, and `.button-primary__accent` etc without the cryptic classes in the HTML.
However, after reading Tailwind, the team found it much easier to write the pre-built classes and stack them as they progressed. And it worked; if I don’t care about how the code is written, things were consistent. It reminds me of “Pixel Perfection” before the responsive design era, when things looked as designed in Photoshop and printed for clients during presentations.
1. https://www.bourbon.io
It is also pretty good configurable utility framework but that is secondary and new version 4 is worse at customisation.
So people are moving to https://unocss.dev/ with tailwind naming conventions.
1. https://tachyons.io/
I doubt that changes your mind, though.
It’s the same as how they enable media queries for example, they’re not using JS just plain CSS, but they’re making it available with these inline classes.
https://developer.mozilla.org/en-US/docs/Web/CSS/:has
EDIT: I'm sorry, I mixed you up with the other user who was replying criticising other people's CSS knowledge.
I don't think Tailwind has a built-in `:has` tool, but I suspect it would be easy to add one as a custom class.
I strongly prefer "button is-primary is-fullwidth" over the long list of tailwind classes.
But consider that a UI is 100% state management and side effects (so fundamentally imperative and asynchronous). On top of that it takes about three revisions for any tool to require bespoke display of something (everybody has an opinion). They also bring a layout engine which is best expressed in constraints.
And somehow we are trying to shoehorn all this into a functional paradigm.
I have used and programmed enough kinds of UIs, since I got coding into that Timex 2068 in 1986.
Nice to see devs picking up web components.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...
You don’t need a shadow dom, you don’t need rerendering of everything when a simple value changes. You simply need web components and scoped js/ts with vite or whatever rollup you use.
More examples:
https://github.com/mdn/web-components-examples
Web components are not analogous to frameworks because frameworks tightly couple the component interface and lifecycle hooks with the component implementations. Those are properly decoupled in web components and you bring whatever rendering layer you prefer.
There are so many framework specific libraries like shadcn, and the community set about building half finished conversions for different frameworks like Vue, which are always several iterations behind and don't really work properly. They have their own version of the docs and it all relies on a specific version of Vue and a specific version of Tailwind and whatever else. It's an abomination.
Start with headless UI as a base and then build wrappers for specific frameworks if you really feel the need. But the wrappers should be syntax sugar only and linked directly to the base library.
I'm sure it's all more complicated than that but a man can dream.
It will also commonly not play nicely with some more advanced aspects of the frameworks, like server-side rendering will probably suffer (depending on how exactly things are done).
In a world where React is dominant and you’re wanting to use React yourself, targeting Web Components just doesn’t make sense.
Then “headless” makes it worse. The more comprehensive implementations have a lot of overhead.
Just a reminder that jQuery was once dominant, too.
We've got some UI components built with html, CSS and JavaScript. They use web standards.
We want to add them into web frameworks that are built in JavaScript. They are built for html, CSS and JavaScript.
No need to overcomplicate things.
And for a universal component library I'll happily accept 7kb extra overhead in my 4mb React slop website
Kind of like how Jeff Bezos threw a bunch of money at 37signals at some insane valuation, which helped them completely avoid the VC trap.
edit: I can’t speak for Adam etc., this is just my impression. My impression is that they want to build a business of which tailwind (the open source project) is one part. I think that regardless of money in the bank they would want to have revenue generating projects. Laravel is a good comparable.
No idea if he still does ok from it, but he certainly did at one stage.
So things are fine but we do need to reverse the trend which is why we are pretty focused on the commercial side of things right now.
We started a corporate sponsors/partner program recently, and I'm hoping that will earn us enough funding to focus more on the free/open-source stuff, since that's where we create the most value for the world anyways. Fingers crossed!
We will see how long it takes for LLMs to make headway in this area specifically.
[0]: https://www.blendful.com
Honestly, I kinda feel like 37Signals would have been better off with the founders having someone to report to...
I have a diagnosed anxiety disorder and I’ve benefited GREATLY from talk therapy in numerous ways. I’m an advocate for therapy. I simultaneously stand behind his post as a healthy nudge for many.
Tailwind Plus (the commercial product) is like buying an off-the-shelf template. It’s just a collection of themes and pre-built components — useful for devs who want to get started quickly on a project, but it’s cookie-cutter and can easily be replicated by anyone with Tailwind itself.
> It’s just a collection of themes and pre-built components
All reusable web components could be described as an optionally themed pre-built component. That's kind of the point.
What kind of integrations are you thinking of?
> To pull this off, we built @tailwindplus/elements — a library we're releasing exclusively for Tailwind Plus customers.
This means if you want to use the Tailwind UI components without a Javascript framework, you have to build them all yourself, or pay.
With so many frameworks out there it's infeasible to build custom wrappers for them all. With web components they can build once, and work everywhere. It's only up to the frameworks to make sure they have great web components support (which just means great HTML support).
Web components are a mess but this is a great application of them: shipping reusable components that work in all frameworks. It's the one and only killer application of web components.
Frankly I'm surprised they're marketing this as "for vanilla javascript" and not as a "now supports all frameworks" type positioning.
TailwindCSS itself is meant to be nothing more than a styling tool, like Bootstrap...
for me the only thing I wish bootstrap had was the money color options tailwind has e.g bg-indigo-400 etc
If it saves you a bunch of time writing and maintaining the sort of components they are showing off, probably worth it?
[1] https://tailwindcss.com/plus#pricing
Edit: apparently all framework integrations and the whole library and functionality is behind the same paywall? And regular tailwind is just the css classes/build process that I used to know? Do people not understand how casual readers might be confused about all this?
It's funny because they're unintuitive to their end users. However, that is deliberate - they are looking for a decision point that comes after, but not too long after, devs have heavily invested in the product.
It's like putting if postgres expected you to pay them a monthly fee.
edit: I see now their pricing is one-time perpetual access. Still, I'm genuinely curious how well this model works.
It's a one-time fee for unlimited use and lifetime updates, not a subscription.
edit:
Confirmed, they removed alpine from their copy/pastable code. Now you see:
<!-- Include this script tag or install `@tailwindplus/elements` via npm: -->
<!-- <script src="https://cdn.jsdelivr.net/npm/@tailwindplus/elements@1" type="module"></script> -->
This sucks because I have been using alpine and now I can't copy paste the examples ~_~
But I understand that funding open source is never easy & I still appreciate tailwind from the bottom of my heart simply because some might hate it for what it is, but I appreciate that I have options to being with (daisy,tailwind etc.)
If anyone who has ever contributed to open source is reading this. Thanks. I am a real frugal person but one day, I want to earn enough money that I can donate to you guys without hesitation and be an open source contributor too.
Well, yeah, because they added an `<el-command-palette>` that specifically does that.
But, if you're building any long-term product, investing in your own design system + component library will put many many more miles on the board in terms of DX, flexibility, aesthethic language, dependency footprint, etc.
https://next.semantic-ui.com/
Has Tailwind support out of the box, just had to mod oxide to get non threaded wasm support in the browser
https://next.semantic-ui.com/examples/tailwind
I just find that at some point, Tailwind gets in the way and I revert back to plain CSS. TW invariably then just becomes another style src in the HTML.
I know Lit is used a lot but I’m always looking for new approaches.
My biggest advice appears to be: remember that the Shadow DOM is optional.
[0] https://worldmaker.net/butterfloat/guides/web-components/
[1] https://github.com/WorldMaker/jocobookclub/tree/main/src/bf
[2] https://github.com/WorldMaker/butterfloat-presentation/pulls...
That has implications for event handling and style encapsulation.
- Despite signals/promises, React 19 didn't add full support for WC. React uses a diff algorithm for reconciliation. There are some rough edges for any "complex value" cases in the incomplete solution for 19's WC support with client vs server side rendering. This results in us being required to use 'use client' for parts of our component architectures, meaning WC providers aren't able to take full advantage of SSR.
- WCs are async loading, which in combination with React can have a negative impact on performance for things like core web vitals (and the dreaded cumulative layout shift).
- WCs are just different from React patterns. Each WC creates a DOM element, but React components don't have to, which just inherently means different shapes of code.
- React focus management libraries don't play nice with WCs. We've talked to multiple devs/companies that were excited about/using WCs that backed out because of cross-ecosystem complexities like this.
- React Native is, uh....a whole thing.
On a somewhat separate note...one of my complaints about TW historically has been that it feels like "just classes" (great!), yet requires a build step (oh...). I'm a little confused to see them leaning into `<script>` tags given that, so am I just missing something?
[1] https://github.com/muxinc/media-chrome
px-3, py-2, bg-red-400 etc. are everywhere in tailwind code and they become more or less undocumented conventions. Technically you can configure them, but practically without unintended side effects on an existing project? And if you make extensive config changes, have you just locked yourself out of the ecosystem?
I don't use bootstrap, but from a brief look at the documentation it seems much more reasonable to diverge from defaults. Looking at themes (https://themes.getbootstrap.com/) it seems more flexible than an average tailwind setup.
I find it very nice that you can re-theme or brand your app with virtually no code or class changes.
Design tokens are the one Tailwind feature I genuinely like. Everything else – kill it with fire. Just use whatever scoped CSS your stack does (<style> in Svelte/Vue, Emotion in React?).
The only "smart" thing about it is leaning strongly on using rem.
how can it spill out onto the page? it's inline css. The (rare) inline selectors target only descendants.
Truth is that it's winning over because it works best with LLMs. Inline soup works better than looking for styling on different files in the context of the project, so here we are.
Because people are lazy and don’t make a component for everything. And some people are even lazier and don’t make UI components at all. I’ve seen a project where there was a Button component and that’s it. Well, that was vibe coded probably so makes sense.
> Inline soup works better than looking for styling on different files in the context of the project, so here we are.
Only if you have a separate .css. If you do UI components with [insert your favourite CSS-in-JS solution], it stays in the same file. Maybe the proximity to markup within the file is important?
But no, Tailwind has been rising in popularity long before LLMs came along.
> If you do UI components with [insert your favourite CSS-in-JS solution], it stays in the same file.
I mean you can but "best practice" all around has been to put them separate and that's reflected in the majority of github repos in the training data of the LLMs.
> Maybe the proximity to markup within the file is important?
that's my assumption, yes. Seems to me LLMs work best when they output the relevant tokens right there with the markup instead of referencing some previous tokens even if relatively close.
styled components was the recommended solution in popular UI libraries like React MUI up until 2023 when chatgpt came out. Tailwind REALLY blew up with LLMs.
I have a daisyui project too, so I might try this later.