Live data from Hacker News

CSS's problems are Tailwind's problems

colton.dev

161–170 of 179 posts

Re: CSS's problems are Tailwind's problems

#161

Since Tailwind looks obviously bad on first pass with all the class spam, I'm more curious to see someone steelman Tailwind. I have some ideas, like how the dead code elimination + granular but consistent classes lets you build novel components that are still consistent with your UI which might be essential for making a 3rd party component library work. I've been using Bootstrap since it came out 15 years ago but it…

> Since Tailwind looks obviously bad on first pass with all the class spam Why is "class spam" bad? Argument? Go read the CSS spec. There's nothing telling how developers/designers how they should abstract their classes. High abstraction classes are, I'm convinced, a holdover of the early days of the web when everyone thought XML and XSLT was going to take over the world. The great thing about functional CSS (especia…

[deleted]

Re: CSS's problems are Tailwind's problems

#162
post #90

Since Tailwind looks obviously bad on first pass with all the class spam, I'm more curious to see someone steelman Tailwind. I have some ideas, like how the dead code elimination + granular but consistent classes lets you build novel components that are still consistent with your UI which might be essential for making a 3rd party component library work. I've been using Bootstrap since it came out 15 years ago but it…

> I've been using Bootstrap since it came out 15 years ago but it never developed a 3rd party component library. I assume because it doesn't have the same sort granular building blocks for building novel components. Except, it does now. Presumably because of the popularity of Tailwind, Bootstrap has all of these inline utility classes, and LLMs absolutely love to spam them across your code. It’s really annoying when…

True, though Bootstrap's utility classes are extremely limited compared to Tailwind's classes. And they aren't very foundational. More like a fast way to bolt on tweaks.

Re: CSS's problems are Tailwind's problems

#163
post #146

Earlier quoted context omitted.

> The closest to that is going back to pure raw CSS which I highly doubt people will do. Huh? Tons of people write vanilla CSS which is getting better every year.

Very very few people, in practice, write vanilla CSS. They use libraries and frameworks often, like Bootstrap. Sure, that might be "vanilla CSS", but you didn't write it, presumably because you didn't want to. Look, after a certain point we have to call a spade a spade and acknowledge that CSS is just too cumbersome, too awkward, and too complicated for most developers and companies. How much CSS do you see that seem…

> Very very few people, in practice, write vanilla CSS.

That's not what I've seen. Most frontend developers I know usually write CSS (or SCSS previously).

> CSS is just too cumbersome, too awkward, and too complicated for most developers and companies.

Really?

I disagree but are you arguing TW solves any of that?

Re: CSS's problems are Tailwind's problems

#164
I think there is going to be a painful Tailwind CSS hangover when it's used and copy/pasted via components like Shadcn UI. It really doesn't belong in design kits or UI component libraries (especially if these are packaged - why on earth would want the Tailwind/Postcss processor reaching into node_modules). But as a convenient utility class-based style system for prototype development or simple apps - it has its place.

Re: CSS's problems are Tailwind's problems

#167
post #32

Earlier quoted context omitted.

If you write enough CSS for a site... eventually you end up building utility classes anyway. Now, you re-invented Tailwind... but in your own proprietary way that nobody else understands. Tailwind takes the inverse approach. The example posted by the parent above is completely unambiguous - what you see is what you get, and it's done the same way everywhere Tailwind is used. You can read the component's styles and un…

When I write CSS, I think in layers: (1) General CSS, global effect, like basic font size (2) semantic components on my pages, like a special kind of list or something, that I give a well thought out name. These CSS definitions are always scoped, obviously to ".my-class-name something" selectors. They cannot affect anything that is not inside a semantic component. It is very simple. (3) layouts/containers, that conta…

To me, the problem is distance. Once a project reaches a certain size, the distance between a thing like a component and where its styles live grows to be too far for mental context.

If you’re working on a page that gets variables from this file, component styles from a scoped style block, typefaces from one file, layout from another…it all becomes a bit much.

Pair that with tooling that doesn’t _seem_ to easily lend itself to discovery - with any function or method or variable in my Vue files, I can tell the LSP to Go to Definition and I’m there. But CSS classes? Maybe. Depends - is there a preprocessor? Is there an abstraction layer that makes it hard to follow? What if someone did an “oops” and overwrote a global style in a scoped block?

On smaller projects or regimented teams, keeping styles in a well-organized structure of CSS/SASS can definitely work. But once you have even a modest handful of imports, or you’re bikeshedding the discussion around how to name classes and variables, it gets unwieldy.

Anecdote time: when I came into my current workplace, our project was already a mess of sorts - Craft CMS, Vue, SASS, just for the frontend. Backend is a separate service that drives a lot of the main content (CMS side is secondary for marketing stuff). The style situation was a mix of SASS in folders for “general stuff”, “project specific stuff”, and “administrative portal stuff”. Oh and then scoped styles per component. There was no clear design language that was shared among teams - the Craft team largely did the original SASS work and painstakingly implemented the design team’s vision for everything from breakpoints to grids to colors to forms. But we weren’t really keyed in on that, and by the time I got there we were rolling up some…50? individual SASS imports plus scoped styles - yikes!

Last year we began the process of separating the various sites from each other - CMS keeps being CMS, customer frontend and admin areas are both separate projects. I made a push to adopt Tailwind and there were the expected “I don’t get it” people and i gave them the crash course on the naming conventions and using the docs. Add the Tailwind LSP and it’s really a no-brainer: we have one single CSS file, per project, that configures things like color tokens and base style overrides for eg breakpoints. Everything else is pure Tailwind.

I’m in a button, my button styles are all right there - no context switching, no hunting down disparate selectors, no worrying if someone slipped an !important into the code somewhere down the line and broke something for everyone else.

I was hugely skeptical of Tailwind some three years ago, gave it a shot, and wouldn’t go back at this point. Sure the syntax is verbose, and I embrace that over the hidden nature of your styles being defined in one (or several) places and your makeup being elsewhere.

Re: CSS's problems are Tailwind's problems

#168
post #86

Earlier quoted context omitted.

And here we’re on firm bike-shedding territory. Where does a utility stop being a utility and start being… a non-utility?

It's less of when it becomes a "non-utility", and more that it becomes an incomprehensible mess of classes on a div.

For me, `class”btn btn-primary btn-primary—title”` says close to nothing about the underlying CSS - I have to go look that up. But `class=“rounded p-2 flex gap-2 items-center font-semibold bg-aqua-300 text-white”` actually tells me something: “this button has rounded corners, padding of 8px on all sides, it’s got flex display with a gap of 8px, items are aligned along the center of the cross axis, font weight is 500, the background is a lighter shade of aqua and the text is white.”

What shade of aqua, exactly? I couldn’t tell you, but my IDE sticks a color block right next to any Tailwind color class. Is that rounded corner a radius of 6px or 8px? I don’t remember off the top of my head, but again my IDE will tell me with a quick hover of the “rounded” class.

To me, the first set of classes is “incomprehensible” because those names, while semantically descriptive, tell me nothing about what the classes actually apply - they describe what they’re styling, not _how_ they’re styling it.

But the long list of Tailwind classes tells me exactly what they do and how they do it, and if for some reason I need to go beyond the LSP to figure out what a class does, the Tailwind docs are miles easier to search than grepping the codebase for “.btn-primary \{“, not that I’ve run into that. In fact, the Tailwind LSP will compute selectors like “[&>div]:hover:border-2” and show you the actual generated CSS selector right in the hover window so you can see what the eventual output will be - it’s not just a dumb lookup of “m-2 is the margin 8px class”

Re: CSS's problems are Tailwind's problems

#169
post #158
post #12

Earlier quoted context omitted.

I do, and it’s great having the styles right there and hackable.

No matter what you are using, they are always there, editable/hackable. However I would argue that it makes it slightly harder to make any change. You no longer have a single class with all the styles that are affecting that element. You can change the classes in the harder to read html, or override the single element. There is no longer the possibility to, for example, affect all .primary-btns.

> You can change the classes in the harder to read html, or override the single element. There is no longer the possibility to, for example, affect all .primary-btns.

Sure there is, the only thing is that instead of having 20 tags, you have a component. Change the component once, and all instances get the update.

This applies regardless of Tailwind. But if you’re repeating classes on the same kind of element over and over, then the question is less about how you’re styling it and more about how you’re organizing things.

Re: CSS's problems are Tailwind's problems

#170

I hated Tailwind when I first used it. > (Tailwind) demands the developer who installs it set up a config file that lays out all codebase-wide style constants > I believe this is where Tailwind has succeeded and other libraries have struggled. This isn't why Tailwind has "succeeded," in my experience. Until Sonnet 3.5, LLMs were pretty awful at creating any sort of UI with normal CSS, but were partially usable with T…

I think I’ll take another jab at this part

> Lastly, Tailwind has also been buoyed by being by being the default styling that just about any LLM or vibe coding tool will produce

Tailwind, afaik, was doing just fine without LLMs “buoying” it - I’ve been using it for several years now and have been pretty pro-Tailwind since getting the hang of it, and it was rare to move to a new project that wasn’t already using it. The idea that LLMs are making it more popular is interesting but I don’t think Tailwind is a ship that would have sunk without them, on the contrary I think it’s been a solid choice for a while now for a lot of good reasons.

Post reply on HN