Comment by azangru
1 day ago
> If suddenly CSS became pleasant to use, Tailwind would be in a rough spot.
CSS is pleasant to use. I know I find it pleasant to use; and I know there are quite a few frontend developers who do too. I didn't pay much attention to tailwind, until suddenly I realized that it has spread like wildfire and now is everywhere. What drove that growth? Which groups were the first adopters of tailwind; how did they grow; when did the growth skyrocket? Why did it not stay as niche as, say, htmx?
People like tailwind because it feels like the correct abstraction. It helps you colocate layout and styling, thereby reducing cognitive load.
With CSS you have to add meaningless class names to your html (+remember them), learn complicated (+fragile) selectors, and memorise low level CSS styles.
With tailwind you just specify the styling you want. And if using React, the “cascading” piece is already taken care of.
The point of CSS is specifically to separate styling and semantics, so that they are not tightly coupled.
If you were writing a blog post you would want to be able to change the theme without going through every blog post you ever wrote, no?
If I'm writing a React component I don't want it tightly coupled to its cosmetic appearance for the same reason. Styling is imposed on elements, intrinsic styles are bad and work against reusability, that's why we all use resets is it not?
I do agree that the class name system doesn't scale but the solution is not to double down on coupling, but rather to double down on abstraction and find better ways to identify and select elements.
Content should come from your database, Markdown, JSON, models etc.
Presentation is determined by the HTML and CSS together.
So your content and presentation is already separate enough to get the benefits. Breaking up the presentation layer further with premature abstractions spread over multiple files comes at a cost for little payback. I'm sure everyone has worked on sites where you're scared to make CSS file edits because the unpredictable ripple of changes might break unrelated pages.
Styling code near your semantic HTML tags doesn't get in the way, and they're highly related too so you want to iterate and review on them together.
I've never seen a complex website redesign that didn't involve almost gutting the HTML either. CSS isn't powerful enough alone and it's not worth the cost of jumping through hoops trying because it's rare sites need theme switchers. Even blog post themes for the same platform come with their own HTML instead of being CSS-only.
> If you were writing a blog post you would want to be able to change the theme without going through every blog post you ever wrote, no?
Tailwind sites often have a `prose` class specifically for styling post content in the traditional CSS way (especially if you're not in control of how the HTML was generated) and this is some of the simplest styling work. For complex UIs and branded elements though, the utility class approach scales much better.
3 replies →
I'll add to my sibling commenters and say that there is a long history of critiquing the value of separation of concerns. One of my favorite early talks that sold me on React was "Pete Hunt: React: Rethinking best practices -- JSConf EU" from Oct 2013 [1] that critiqued the separation of concerns of HTML templates + JS popular in the 2000s and early 2010s and instead advocated for componentization as higher return on investment. I think people already saw styling separation of concerns as not particularly valuable at that point as well, just it wasn't clear what component-friendly styling abstraction was going to win.
[1] https://www.youtube.com/watch?v=x7cQ3mrcKaY
I do want styles tightly coupled to my React components. The product I work on has tens of thousands of React components.
I don't want to have to update some random CSS file to change one component's appearance. I've had to do this before and every time its a huge pain to not affect dozens of random other components. Other engineers encounter the same challenge and write poor CSS to deal with it. This compounds over time and becomes a huge mess.
Having a robust design system that enables the composition of complicated UIs without the need for much customization is the way.
1 reply →
I think the problem is simply that css is too restricted that you can style a fixed piece of html in any way you want. In practice, achieving some desired layout require changing the html structure. The missing layer would be something that can change the structure of html like js or xslt. In modern frontend development you already have data defined in some json, and html + css combined together is the presentation layer that can't really be separated.
You’re kinda late to the party. 15 years ago that was the way to build UIs, but componentization changed that. Now we reason about UIs as blocks, not as pages, so collocation of logic, markup, and style makes the most sense.
Not to say that every component should be unique, generic components can be built in an extensible way, and users can extend those components while applying unique styling.
Theming is also a solved issue through contexts.
Reducing coupling was never a good idea. Markup and styling are intrinsically linked, making any change to the markup most likely will require changes to the styling, and vice versa. Instead of pretending we can separate the two, modern UI tools embrace the coupling and make building as efficient as possible.
2 replies →
> The point of CSS is specifically to separate styling and semantics, so that they are not tightly coupled.
That was the original point, and it turned out that nobody cares about that 99% of the time. It's premature optimization and it violates "YAGNI". And in addition to not being something most people need, it's just a pain to set and remember and organize class names and organize files.
Remember CSS Zen Garden from the late 90s? How many sites actually do anything like that? Almost none.
And the beauty of Tailwind is, when you actually do need themes, that's the only stuff you have to name and organize in separate CSS files. Instead of having to do that with literally all of your CSS.
1 reply →
You're talking about separation of concerns (SOC), as opposed to locality of behavior (LOB).
This is the insight that Tailwind and others like HTMX made clear: Separation of concerns is not a universal virtue. It comes with a cognitive cost. Most notably when you have a growing inheritance hierarchy, and you either need 12 files open or tooling that helps you understand which of the 482 classes are in play for the specific case you’re troubleshooting. Vanilla CSS can be like that, especially when it’s not one’s primary skillset. With Tailwind you say ”this button needs to be blue”, and consolidate stuff into CSS later once the right patterns of abstraction become clear. Tailwind makes exploratory building way faster when we’re not CSS experts.
SOC is usually a virtue when teams are split (frontend/bavkend, etc), but LOB is a virtue when teams are small, full stack, or working on monoliths (this is basically Conway’s law, the shape of the codebase mirrors the shape of the team).
People who have tried both throughout their careers are generally sticking with Tailwind. I didn’t get it at first either, but after using it extensively I would never go back to the old way.
disagree. Colocation seems great when authoring, but it comes at a big cost of downstream tech debt
there could be better ways to ease the burdon of naming things, while preserving cascade and the actual full features of CSS
Tailwind is a mirage, a shortcut to not having to do the important stuff by stacking wrappers on top of wrappers and redundancy
And the "fragile" part is exactly the same thing with tailwind, it all remains low specificity class names
Every line of CSS you write creates tech debt, it has nothing to do with tailwind.
Those are the same selling points as CSS-in-JSS libs like Styled Components. Or CSS Components.
Except your last point about "low-level CSS styles" which I'd argue is a weak point. You really should learn the underlying CSS to gain mastery of it.
Not arguing for one thing over another, just saying Tailwind really never had anything to offer me personally, but maybe if I wasn't already proficient in CSS and the other 2 options didn't exist it might hold some appeal for me.
It’s more about cognitive load, and abstraction level. If you’re trying to make an object spin, it’s much easier to use the tailwind class than it is to remember css keyframes.
Sure, when debugging a complex issue, it’s worth knowing the low-level, but CSS is not a great abstraction for day-to-day work.
Can you suggest a best place to learn CSS in-depth, from first principles? (as opposed to, say, simple tutorials)
2 replies →
You’re right that it’s not much more than a css in js library, but I’ve found myself pleasantly surprised at how efficient I am using it, despite also having years of css experience.
Things like remembering what the flex syntax is, or coming up with a padding system or a colour scheme become very very easy.
I think the editor tooling for tailwind is where most of the benefit comes from.
I also prefer the syntax over direct css in js systems. It’s less characters, which means it’s easier to parse.
Give it a try, you might be surprised!
Imo CSS is not pleasant to use, but Tailwind is at least as bad and furthermore is bad in addition to the CSS badness which it does not fully replace. It is a mystery to me as well how it got so popular.
(I know many people disagree, which is fair enough.)
Writing CSS manually was never all that pleasant for me, mostly the part about debugging it when it doesn't do what I want.
So I tried Tailwind and it seemed to help.
But now that Claude Opus 4.5 is writing all my code, it can write and debug CSS better than I can use Tailwind. So, CSS it is.
Debugging CSS nowadays is way easier than even 5 years ago. There are a lot of cool browser debugging tools for animations, z-indexes. The browsers have come a long way since firebug. Definitely look into both chrome or firefox, their tooling is great. Especially firefox, they have debugging tools where you can create css shapes in the browser and save them. Very handy for those artsy fartsy sites.
Claude can also write and debug tailwind for you! :)
I used plain CSS for more than a decade and felt the benefits of Tailwind within 10 minutes of getting started. What fueled the growth of Tailwind is that it makes web development palpably easier.
What were the benefits that you felt instantly? I still don't feel anything and would prefer plain CSS over Tailwind any day.
I first took a css courses to get the basics then didn’t do much with it, then tailwind came out. I had used bootstrap, but always struggled to get stuff to look nice. I’m not doing web dev most of the time. So it was much easier to memorize tailwind utility classes than css. These days with ui frameworks like daisy, shadcn, tailwind is pretty easy for doing something simple for an IT dev tool but still customize it.
For creativity, I wished I had the time to get really good with css. It really seems to have grown a lot. Using sveltekit, its really easy to get component scoped css
It lets you apply styles to a single element without it messing up the whole rest of the page/site/app. i.e. it disabled the primary feature of CSS, the thing most people don't want from it.
18 replies →
Honestly, for me, tailwind was just pleasant to work with and pure css definitely was not.
And I was super skeptical about it at first. I almost said no to it, but I trusted our main ui guy and wanted to allow him autonomy. And I ended up loving tailwind after working with it.
Do you remember what made it click for you? What was the hard part of writing plain CSS that tailwind made significantly easier?
CSS requires discipline, or you end up accidentally styling something completely unrelated because you were overly general, or overly specific, or accidentally reused a class name. CSS disallows local reasoning. If you’re writing markup for a component, you have to jump between two files.
There are plenty of other problems Tailwind solves, but these two alone make me never want to go back.
9 replies →
> What drove that growth?
It is a natural fit with component-based frontend frameworks like React. You keep the styles with the component instead of having to work in two places. And it’s slightly nicer than writing inline styles.
The core CSS abstraction (separating “content” from “presentation”) was always flimsy but tailwind was the final nail in that coffin.
Then of course LLMs all started using it by default.
You've been able to keep the styles in the component well before tailwind turned the class attribute into ersatz inline styling. CSS-in-JS has been around for a decade, and there are myriad options for react. Vue and Svelte have them built in.
Fe devs who refuse to learn css and instead use tailwind have always struck me as incredibly odd. It's like a carpenter who refuses to use a hammer because they hit their thumb once as an apprentice
I wrote this piece on tailwind a few years back, and little seems to have changed https://pdx.su/blog/2023-07-26-tailwind-and-the-death-of-cra...
It’s interesting to me because CSS is very stable. It doesn’t really change that often. It’s great foundational knowledge to have for people who build for the web.
And nearly every step it's made has been for the better. I used sass on that blog, because a few corner case features weren't widely available when I last did work on the style, but for the last 3 projects I've worked on, I don't use it anymore. Pure css can do basically everything I needed before. Sure, I bundle using bun's bundler, but that's for performance optimization, nothing more
backend devs needing to be fullstack but consider frontend to be beneath them
I'll give my guess - it's because of rhe "fullstack" bullshit.
I am a backend developer. I like being a backend developer. I can of course do more than that, and I do. Monitoring, testing, analysis, metrics, etc.
I can do frontend development, of course I can. But I don't like it, I don't approach it with any measure of care. It's something I "unfortunately have to do because someone who is not a developer thought that declaring everyone should be doing everything was a good idea".
I don't know how to do things properly on the front end, but I definitely can hammer them down to a shape that more or less looks like it should. For me, shit like Bootstrap or Tailwind or whatever is nice. I have to spend less time fiddling with something I think is a waste of my time.
I love working with people that are proper front end developers for that reason, and I always imagined they would prefer things more native such as plain CSS.
> CSS is pleasant
So is SQL. To me. But some otherwise rational people have an irrational dislike of sql. Almost like someone seeking to seal a small bruise with wire mesh because bandaids are hard to rip off. The consequence shows with poorly implemented schema-free nosql and bloated orm tools mixed in with sql.
But some folks just like it that way. And most reasons boil down to a combination of (1) a myopic solution to a hyper specific usecase or (2) an enterprise situation where you have a codebase written by monkeys with keyboards and you want to limit their powers for good or (3) koolaid infused resume driven development.
Decades of SQL hate eviscerated in one comment! /s
Is CSS pleasant in teams of fullstack (not CSS specialists)? Not in my experience. It becomes a maze of Chesterton's fences.
I would have understood if tailwind got popular primarily among full-stack or backend developers: people who have neither time nor interest to learn CSS deeply. But, what contradicts this expectation is that one still needs to acquire CSS knowledge to use tailwind, and that some front-end developers seem to prefer it as well. Although I still cannot tell whether there are more front-end developers who prefer tailwind over plain CSS than the other way around.
I was too subtle but the issue is less understanding CSS and more collaborating in a team where someone decides to add a specific rule that fixes something applies on every page but makes no sense semantically.
Then do that 100 times to create spaghetti. CSS rule anywhere can affect anything whereas tailwind is more local.
You can also bricklay it along lines of components in React, so you know how X component renders always and it wont look like a pig when tranplanted to the legacy billing screen.
I now recall why I like tailwind! Been backending for a while now (zero regrets lol)
3 replies →
Tailwind is just bootstrap with marketing budget
nah
I haven’t seen this mentioned much, but Tailwind’s rise closely followed a shift away from runtime CSS-in-JS toward build-time, deterministic styling.
Many JSX-era libraries (MUI, styled-components, Emotion) generate styles at runtime, which works fine for SPAs but creates real friction for SSR, streaming, and time-to-first-paint (especially for content-heavy or SEO-sensitive domains).
As frameworks like Next.js, Vue, Svelte, Angular, and now RSC all moved server-first, teams realized they couldn’t scale entire domains as client-only SPAs without performance and crawler issues.
Tailwind aligned perfectly with that shift: static CSS, smaller runtime bundles, predictable output, and zero hydration coupling. It wasn’t about utility classes. It was about build-time certainty in a server-rendered world :)
Your examples, Vue and Svelte, give you build-time predictable output with scoped CSS without Tailwind. All the benefits and none of the downsides!