(评论)
(comments)

原始链接: https://news.ycombinator.com/item?id=43809484

Hacker News 上讨论了 CSS Zen Garden 及其对早期网页开发的影响。评论者回忆起基于表格布局的 CSS 时代之前的状况,以及最初对 CSS 的抵制,当时 CSS 被认为限制了设计。Dave Shea 的 CSS Zen Garden 演示了 CSS 的能力,消除了“单调乏味,像盒子一样”的误解。 对话随后深入探讨了 CSS 的演变。早期的 CSS 限制、浏览器兼容性问题以及对额外 HTML 的需求是巨大的障碍。现代 CSS 功能(如 flexbox 和 grid)改善了局面,但讨论也涉及到 CSS 组织、特异性以及 Tailwind CSS 等工具的兴起。一些人批评 Tailwind 模糊了语义 HTML 并阻碍了对 CSS 的深入理解,而另一些人则为其在大型项目中保持一致性和易于重构的实用性进行了辩护。关于结构与表现的分离、语义 HTML 的作用以及约定与实用性之间的平衡的争论仍在继续。


原文
Hacker News new | past | comments | ask | show | jobs | submit login
CSS Zen Garden (csszengarden.com)
290 points by onat1 21 hours ago | hide | past | favorite | 127 comments










There’s an aspect of this that is not readily apparent unless you were a web developer around the time this was created.

Before CSS, layouts were implemented by abusing table elements to create a grid. Then images were sliced up into sections, and each section was placed into the table. This has generally been remembered in the present day, however what seems to have been forgotten was the pushback against CSS.

There was a large number of web developers who were happy with the status quo and refused to learn CSS. One of the most persistent myths was that you couldn’t make anything look nice with CSS. Specifically, CSS was accused of only being able to create “boring, boxy” designs.

It wasn’t true at all. Even back in the early days of CSS, you could create great layouts. It was especially absurd because the approach favoured by the people saying this was literally abusing tables to create grids.

So along comes Dave Shea and points out that this is ridiculous, that CSS is capable of great designs, and puts the CSS Zen Garden up. A whole bunch of people contribute good-looking designs and make it impossible for people to claim that “CSS can only produce boring, boxy designs”. I think it’s amusing that he won the argument so conclusively that people forget it was even an argument in the first place.



Not to mention that early on, CSS was very lacking compared to today. We didn't even have `border-radius` until something like 2011! Consider that this relatively simple site design[1] takes about 420 lines of modern CSS[2]. And that's even using nesting, and liberal use of :has, which is a game changer. I remember having to restructure both my CSS and my HTML to achieve appearances which were otherwise impossible to create in the intuitive way, all because of inherent limitations to CSS at the time.

[1] https://90s.dev/

[2] https://90s.dev/style.css



Re border radius… The coveted rounded corner, the mark of a really slick design before that property made it easy :D

I think media queries/responsive is what did in the last bastion of CSS resistors.



Modern CSS makes me long for Hi5 to make a comback. My profile would be killer.


The reason we used tables was because getting things right in CSS in the early days across all of the browsers was a nightmare. An expensive nightmare. Which was fine if you were a well funded startup and could afford to rebuild your HTML regularly.


CSS at the time was still a leaky abstraction: in order to get things working, you had to include extraneous DIVs in the HTML code as anchors for the CSS rules. The standard body has attempted to address this issue with pseudo-elements and pseudo-classes as well as other features I may not be aware of.

At least though, these extra DIVs weren't disrupting the page layout (eg. when disabling the CSS - something that was still possible at the time), which was beneficial for accessibility.



The “across all browsers” problem was such a huge pain. Not just for CSS but JS too.

I still remember the campaign for sites to drop support for IE6 in protest.



Yeah fun times.

I kept our internal reporting site running for 3-4 years, I used CSS for layout.. it required regular maintenance but I had enough time to do it as my main job was as a Database Admin / Data Engineer (I'd have been called "devops engineer" nowadays as I had quite a broad set of responsibilities).



It always felt like a fun challenge. For me, it was a crucial part of my love of the web (and eventually, programming): the hackability and the way that there was no canonical correct way to solve a given problem. I miss those days.


I remember a time when using
tags was considered a sign of "expensive" to some.


I'm fuzzy on the timeline, but there was a time where the emerging CSS wasn't up to the task of creating more complex layouts (no flexbox, not to speak of the grid). CSS Zen Garden was just there to show what could be done by that point.


Things have certainly gotten easier, but even back then CSS had things like pseudo-elements and display: table-cell. The main problem was Internet Explorer 6 holding everybody back so floats were the main way of laying things out, and those go back to CSS 1 (1996).


floats and clearfix were plenty powerful even before flexbox, despite not being intended for the purpose.

But then, neither were tables.



Ahhh yes, floats were everything.


> layouts were implemented by abusing table elements to create a grid.

Never understood what was actually wrong with it, apart from the whole "semantic html" yadda yadda that is meaningful for a small subset of applications.



On the contrary, semantics are very important from accessibility point of view.


Yeah me neither, I think the CSS being cool and hard to use was the real reason. People like being ”elite”, and tables were just dead simple.

I am surprised people here still hold on to that era of CSS. There are even people in the comments being proud of clearfix

But I should probably be thankful for CSS for getting me out of webdev early :)



>> layouts were implemented by abusing table elements to create a grid.

> Never understood what was actually wrong with it

Separation of concerns?



Creating a grid is exactly the purpose of a table, not an abuse.


Semantically speaking, tables are supposed to contain tabular data, not to be used solely for their layout capabilities. That's why it's called an abuse.


> Tables have existed as part of web standards since the HTML 3.2 standard (January 1997). The standard referenced an earlier RFC and was intended to be compliant with the table tags Netscape had already added to their browser, but this was their official addition to the HTML standard.

> The standard pointed out that tables could be used for tabular data or layout purposes, but cautioned that using them for layout would impact accessibility.

> In HTML 4 (April 1998), this warning was strengthened to "Tables should not be used purely as a means to layout document content", and we were pointed to the addition of CSS1 to help accommodate this. It was noted, however, that using deprecated features was expected to continue for a little while [heh] in order to support older browsers (browser listed above).

https://www.tiernok.com/posts/history-of-html-table-layouts....



An HTML table describes data that is related across multiple axes. A grid is a typical presentation for that data. That does not mean that creating a grid is the purpose of a table, and it doesn’t mean that any instance of a grid should be a table.


With all due respect to Dave, no. Please stop rewriting history without the relevant details.

CSS Zen Garden is a project that demonstrated that "progressive enhancement" and "semantic HTML" were nonsense. The only reason something like CSS Zen Garden worked at all is because all the markup is fixed, all the content is static, and the designs are not really responsive.

There is no CMS with a theming system that offers the flexibility that CSS Zen Garden claims one can have with a single .css, independent of the HTML. And this is because web developers were huffing the HTML/CSS gospel too much, fussing over not having extra divs in their source and what not, and celebrating "semantic HTML" without ever running their website through a screen reader.

The reason people stopped using table layout when they were doing CSS is because CSS1 did not support the _most common way of doing layout at the time_, and IE6 held the web hostage for a decade. This is a remarkable thing because it means everyone hopped on this bandwagon despite it being very obviously ill-informed and not ready for production. The CSS Zen Garden era designs can be expected to be full of float/clear tricks, requiring careful layout dependency between elements so everything gets pushed down just far enough. And it looks exactly like the table-based layouts they were replacing, except they will scale improperly or not at all.

The "status quo" attitude has also not vanished, as witnessed by CSS variables, custom properties and all the other epicycles that keep getting added on to CSS instead of actually just scrapping the parts that are dumb. None of these CSS experts have the vision or depth of experience to really know what it takes to implement what they spec, or what is even still relevant today and what isn't.

I actually implemented my own web layout system for Use.GPU from scratch, with flexbox and blackjack and hookers, and it's remarkable how much of HTML/CSS you don't need, and also, how many parts of it are still laughably inadequate (like text-ellipsis).

Dave did not win the argument. The people who celebrated CSS Zen Garden were cargo culters who confused a pretty design for a structurally sound layout, and who honestly just wanted something they could feel good about while dealing with pre-Firebug / pre-Dev Tools CSS development.

There is a really easy way to test this too, and I would challenge Dave to do it: translate all the content to another language. See how many of those beautiful CSS-only designs fall apart.



This sounds less like you want to correct something I have said that was inaccurate and more like you have a fundamental disagreement with the design of CSS.


If that's how your feel about CSS, what do you think about XSLT?


You could easily make float/clear layout for dynamic content.


> [IE] held the web hostage for a decade.

I wonder whether we'll ever get to reach this point with Safari. Especially with regards to PWAs and the insane state of "native" apps.



This site is old, and I mean it in a good way.

This site was a "culture" shock for me, back in 200x and made me walk away from Microsoft ASP.NET and start building apps on linux, realizing all those "server controls" with inline style parameters were basically the complete wrong way, the "anti internet way".

It was Alex Russell (creator of Dojo JS) who showed that side in one of the conferences, and I was shocked how much information I was missing while getting my technical news through Microsoft channels.

For many years, my toolkit was simply Web.py, HTML, JS and CSS.

We then got jQuery, and Backbone, and Underscore, till the React and then TS made new "Full stack" dumber again.



> This site was a "culture" shock for me, back in 200x and made me walk away from Microsoft ASP.NET and start building apps on linux

What stopped you from building such apps on Asp.net? It didn’t prevent you from building anything like that. You could stop creates style sheets and separate JS files.

> realizing all those "server controls" with inline style parameters were basically the complete wrong way, the "anti internet way".

Ironically what’s old is new again because we have literally gone full circle even down to nextjs? Recreating view state… and tailwind with inline styling and shadcn with react components.



Indeed. The famous asp.net "__VIEWSTATE" is now back to life...


> made me walk away from Microsoft ASP.NET and start building apps on linux, realizing all those "server controls" with inline style parameters were basically the complete wrong way, the "anti internet way".

That's still online, although as an outdated relict: https://www.ajaxtoolkit.net/. There was no enterprise software without drag panel!

For a moment semantic markup and CSS had taken the lead but nowadays I don't even care enough to check what the trends are. Stopped caring around the moment of "HTML inside JavaScript" (JSX).



I started writing ASP & PHP, the whole ASP.Net thing was about helping Visual Studio developers make crappy web apps, it wasn't fit for purpose for the web writ large.

You didn't need to switch to Linux either; I built everything under Windows (IT didn't allow Linux desktops) and deployed it to both Windows and Linux servers.



Svelte now exists; it's a bit of a "clever" fullstack


I feel like the main point of css zen garden was how, by maximizing your use of semantic HTML, you could separate the presentation from the content and operate on them completely independently.

While you can still do this to the extent zen garden does, it's really operating within the limits of css (i.e. css can do this, therefore I can create this type of design, not I want this type of design, therefore I need to write this css).

There are lots of style choices that require modifying the DOM directly to effect, and can't be done purely with CSS. I've seen discussions on W3C where it was like "Well if you add another div around this you can achieve this effect, so why do we need a new CSS property?". Stuff like inserting or swapping an image is simple, but swapping a styleable SVG is impossible because the SVG nodes need to be directly embedded in the html.

So you're forced to mix presentation and content structuring decisions at the HTML and Javascript levels and even some simple design changes require modifications throughout the stack.



The CSS community's promise was always that structure and presentation can be separated.

After my 30 years of writing GUIs, I'm now convinced that this is the wrong place to draw a dividing line.

Instead, we should be isolating intent. This is what Composites do in my project. I'm so excited to announce it next week!



Enter stage: XSLT


On the other hand CSS is very capable these days and many designs, that actually are not flying air castles and take the medium into account, can be implemented flawlessly using only CSS and HTML.


Agreed. A lot of modern web design problems come from trying to force a medium to do something it was never meant for. If you work with the grain of HTML and CSS instead of against it, you can still build really flexible and beautiful layouts without needing to hack the DOM or pile on JS. zen garden was a reminder of that and it still holds up.


As someone who learned CSS from Zen Garden and the likes of Eric Meyer, modern css tools like Tailwind looks like an anti pattern


Absolutely! There are so many problems with Tailwind.

The HTML is littered with styling information. Reading HTML should be about content and meaning, not knowing that "pl-16 pr-8 bg-olive-500 text-gray-700" means "this is probably a card header". But... you might argue that people do not read HTML anymore. Yes, people don't read HTML anymore. Who would when the devs using this framework turn the HTML into a horrible mess! If you litter your HTML with so many framework classes, there is more noise than content in HTML. Is it a surprise that reading HTML has fallen out of fashion? And since nobody reads HTML anymore, devs are totally unhinged with cluttering it with more and more classes and styles. It's a self perpetuating cycle.

Webdevs do style duplication rampantly. Instead of something like ".button", you'd find stuff like "text-white rounded bg-gray-aaa" littered throughout hundreds of places. I'm not sure if this is a Tailwind problem or dev problem but the problem definitely is there. A large project would soon reach a situation where if you want to make a style change across all similar UI elements it's a whack-a-mole game to find out which inline styles in which elements you need to look at.



I have a fairly strong grasp on CSS, at one point having what I felt was as close to as knowledgeable as I'd care to be about it, but one thing always stuck out as a neverending battle; style organization. I think Tailwind does have all those problems to some extent, but CSS alone didn't find cultural consensus around how best to implement it, always leaning on whichever flavour of the month conceptual framework that was often just one more system to try to manage. There's some virtue in writing the stuff you do cleanly, but sometimes it's just not as valuable to someone who's primarily doing what could be described as complex software development. Sometimes the marginal benefit to a clean implementation and a slightly messy redundant one of the same interactive caliber just isn't that important relatively, especially when the negative qualities are somewhat mitigated by component re-use and scoping.


I think it's the complex specificity rules that prompted things like TW to come about. Sure it's useful and powerful but it's utterly baffling to reason about, especially when everyone's conventions work at a different level of specificity. Trying to tame specificity gave us cumbersome structures like BEM, and TW came about as an act of rebellion against such things.

Conversations about CSS complexity always remind of this quip: "Two CSS selectors walk into a bar. A bar stool on the other side of town falls over."



It's a culture problem with Tailwind devs: for a long time there was a crusade against `@apply` in favor of inlining every class. I think the reason was solely because TW's tree-shaking wasn't very capable then and did even worse with @apply, but the air was thick with specious "philosophical" justifications flying around for inlining all the things. The most typical was "it should always be done through a component toolkit", which of course just buries the problem in javascript -- not to mention doing it dynamically is incompatible with tree shaking, so you end up having to predeclare everything you use...

Nowadays the anti-@apply contingent seems to have gone quiet, so it is possible to not only use TW and similar toolkits sanely (which has always been the case) but to even see people publicly advocating for sanity.



yeah, and then one day you want .button, but with a variation. GREAT. but oh no, now there's this other button that has a little bit of a change but not enough to create a separate class. maybe we'll just inline it... but no, i need a mobile selector here or i have some complex hover style. i know, let's create a basic utility class to help me out here. hmm, starting to look suspiciously like tailwind...

now multiply this problem by more people working on an app, with different isolated components that they never even dreamed of during css zen garden's time and this is how something arose. we've tried creating centralized css sheets and it just doesn't work at scale.

so yeah, a necessary evil, but i wouldn't call it an anti-pattern. it grew out of real needs. we had bootstrap and all these css frameworks attempting to make "order" about of something that honestly after decades of working with i don't think can be ever be fully "clean". people just gotta move past it.



I think CSS tools like that appeal to people who learned web development in a kind of ad-hoc way. When I first started, I just wanted to make designs I had in my head. I kind of went from "header, text, and image on the page" to, "how do I center this?", "how do I change this color?", "how do I space these elements out?" It wasn't long before I had developed a toolkit of CSS ideas, but once you do that, you lose out on a lot of the finer details that make CSS work well. I knew how to work around weird issues using position: absolute and transform, but I wasn't familiar with block formatting contexts, or the intricacies of the box model. When all of your CSS knowledge is just band-aids placed on your other shoddy CSS knowledge, you're working on fumes. At that point, you could imagine the appeal of grabbing a prebuilt toolkit of composable styles that takes away your access a lot of the available CSS footguns.

What changed things for me was reading an short online book-style series about learning HTML/CSS from the ground up. It introduced everything from first principles, and had an approach where they explained why things were the way they were. They didn't just give you their "top 10 ways to center a div" and ask you to leave. I read the whole thing in an afternoon and it changed the way I think about web development. For the life of me, I can't remember what the book was called. If anyone's read something similar I'd love a reference, it was a while ago now and I'd still like to reference it. I specifically remember them saying "display: block is like a word document, and display: flex is like how you'd expect things to work," which illuminated a lot for me, not just about the display property, but generally about the way HTML & CSS were designed.



> What changed things for me was reading an short online book-style series about learning HTML/CSS from the ground up.

Do you remember which one? Your experience sounds a lot like mine and I’d love to learn CSS from first principles.



I think it works well and is a good standard for companies with hundreds of people. Want to style everything one-off in a landing page go ahead.


A bit of light in the dark ages of Tailwind and CSS-in-JS.

It's difficult to realize how significant CSS Zen Garden was 20 years ago or so.



CSS-in-JS (like how Styled Components and Emotion do it) is primarily a solution to code organization. It doesn't fundamentally change how CSS works.




It can be, depending on how it's used. But most of the modern tools I've seen are specifically designed to compile away the dynamic aspects of CSS-in-JS, meaning it essentially becomes a different way of writing normal CSS.


It made me fall in love CSS for sure. But it didn’t prevent me from understanding the appeal of Tailwind for large scale projects.


Please enlighten me of the benefits of using tailwind in large projects as opposed to using inline styles.


Not having to name a myriad of things! Sure, things like BEM can help you at least avoid naming conflicts, but you still have to decide a few thousand times what something is called semantically correct, in a way that you and your French colleagues and the intern of next year are going to understand it.

When I got productive with Tailscale, I finally realised how many brain cycles I wasted on this. I’m, like, a programmer; of course I’ll obsess over picking the perfect name. Of course I will not be happy with the names my junior picked, and of course I will constantly be unhappy with some of them. This game of self-inflicted bike shedding is just a trap for people that like logic and order, and it’s… wholly irrelevant.

With tailwind, you just declare how something is supposed to look and feel like, at the place where it is, in the context of your configurable design system. No names, no bike shedding. Okay, that’s not a hundred percent true; you can name group selectors, because as opposed to plain inline styles, Tailwind can target children, siblings, pseudo elements—there are no restrictions.

It’s a truly elegant solution for authoring web pages.



How do you cope with page URLs, with JavaScript classes, variables, methods, Git branches, CSS filenames, image filenames, directory structure, etc.?

I know the joke is that naming things is hard, but it really isn’t and every web developer successfully and effortlessly names things all day long without even thinking about it.

If I have a sidebar, coming up with the name “sidebar” for a CSS class is not a serious problem I need Tailwind to help me avoid. I don’t find it plausible that other people genuinely feel pain over this one particular instance of naming things without demanding solutions for all the other things they have to name. Can you point to many Tailwind advocates who complain about how difficult it is to pick filenames, or page URLs?

I think it’s really strange Tailwind advocates latch onto this one particular thing – naming things is a problem – when they seem to successfully name things all day long in every other context. It doesn’t feel like a real problem. What happens when you need to create a file? Do you get paralysed by the myriad choices of filenames available? Or do you just pick a name and move on?



I don't do front end these days and don't really have a dog in this fight, but most code is nouns and verbs, while design choices are adjectives and adverbs. When the business decides that we need to run, not walk, you can just change the name of the function from walk to run instead while changing the code, if that seems appropriate. With CSS selectors, when the business decides we need to change the "feel" of the page from "spiky" to "gentle," you might only want to change some subset of the design that was built up around the "spiky" concept, while leaving others as they are. There is not a comprehensiveness and absoluteness to the changes, and it's a lot harder to reason about "pure functions".

Add to this that CSS is like a codebase built on try/catch and throwing errors for its primary control flow mechanism, where the only thing that tames this is the naming conventions employed, and you've got a situation where the names really matter in a way that they don't when we're doing other programming, because the names are the only connective tissue to help you reason about the "control flow" once your css starts getting complex.



Naming things involves creating an ontology that makes sense. In the context of URLs, that’s an hierarchical structure of things that’s self-describing; in the context of code, it’s a direct model of the domain logic underlying the problem, at least for the most part: There’s lots of code involving "managers" and "containers" and "controllers" and "factories". That’s where it starts to get murky. Meanwhile, CSS classes require creating an ontology of things that’s both reusable, and at the same time referring to small or partial aspects of a thing, sometimes a thing that shows up in other parts of the code, sometimes as a variation, or just a one-off occurrence. If you do it properly, that means you’ll need to find a shared vocabulary for button attachments, centered max width wrappers, field hints, list items, and so on. It’s draining, because it’s not productive. The end result is just hopefully maintainable style sheets.


Using webcomponents there is no problem with identifiers, you can repeat the same identifier as many times as you need.


Do you treat your JS and TS the same way, eschewing semantic clarity?


Why do you assume there's no semantic clarity?

Tailwind is made for the age of apps and components. The semantics are on component level.



So you can name a component, but you cannot name the styles attached to that component?


It’s naming one component, perhaps a sidebar, versus naming the fifteen children of the sidebar and their state transitions, in a way that’s consistent with the other 137 components that comprise your app.

It’s not about not being able to name all these things, it’s that it’s pointless to do so.



You don't need to name subcomponents in a way that is consistent with the rest of the app, or even at all. That's what nesting is for. You can use simple names, or anonymous tags, that don't overlap because they live in a top level component with its own class/id.


Isnt that what scoping is for? So you name you conponent and use selectors for styling sub components.

My issue with most styling is that they want to use composition when it does not make any sense. Like spliting styles and using the pieces on things that has no relation to each other. If two things are not likely to change together, you shouldn’t use the same class for them, unless you consider the class as primitive.

Tailwind is an extreme case of this, and like all extreme things, it’s a path to ruin.



> If two things are not likely to change together, you shouldn’t use the same class for them, unless you consider the class as primitive.

That is exactly the kind of dogma that I'm referring to—Tailwind makes thinking about that pointless. You apply style composition to achieve the result you want to achieve; not more, not less.

> Tailwind [is] a path to ruin.

Well, I can only speak from the experience of quite a few very successful projects relying on Tailwind: They look consistent, development is easy, style bundling an issue unheard of, and making changes to the design system requires a single line in the config file. New developers are productive from day one, there's no bike-shedding over the styles, and nobody adds ad-hoc colors they just pulled out of their hat.

For me, styling on the web is solved.



I get your point, but isn't this contingent on the colors and other properties being stable? I don't see why this can't be achieved with pure CSS instead of adding a (big) set of names as a layer of abstraction and then optionally pruning the build for performance.

Because consistency is achieved only at UI design time (see design system). Unless you're prototyping your design at development time, I don't really see the improvements compared with Pure CSS.

> style bundling an issue unheard of

But then you need to have a component system to have any benefit from that (if you're using the raw classes name from Tailwind). Which was easily done with just naming the component (class or ID) either automatically or not.



> Because consistency is achieved only at UI design time (see design system). Unless you're prototyping your design at development time, I don't really see the improvements compared with Pure CSS.

So, every class now repeats the same properties and values (because CSS has no mixins or composition), there are dozens of classes that try to replicate scoping and nesting through BEM or similar, styles are completely divorced from actual components where they are used...



This is what I highlighted in a previous comment. If you have a drop shadow or some padding on a component, that does not mean another component which have the same values automatically have a relation between them. So it’s mostly a syntactic shortcut at this point. And the end result has no semantics.


> Isnt that what scoping is for?

The one that hasn't been available in CSS until 2023?

> So you name you conponent and use selectors for styling sub components.

So how can you do that with CSS?



> So how can you do that with CSS?

The old:

  .card > .card-header
> The one that hasn't been available in CSS until 2023?

That was nesting, IIRC. Sugar syntax, so you don’t have to fully specified the whole selector.



Because you honestly don't need to, and shouldn't need to.

CSS missed out on scoping, nesting, and composition even though most of these things have been available elsewhere (notably, SASS) for 20 or more years.

What you really want is to have a component and all styles scoped to it. In the absence of that you want as few names replicating scoping, nesting, and composition, as possible. And you want to compose repeatable patterns across all of your components (something that is possible with mixins, and is impossible with vanilla CSS). So you cut down on repetition across class names until you're left with utility classes and a separation of concerns that cuts a different way: https://x.com/simonswiss/status/1664736786671869952

Note: no one is stopping you from having your own arbitrary classes when you need to. See e.g. Cube CSS approach https://piccalil.li/blog/cube-css/



What I’m arguing about is that composition isn’t necessary in most cases. Because all components evolve independently. Also nesting is syntactic sugar, nice, but orthogonal to these discussions. And scoping is done with selectors.

CSS isn’t an imperative language. It’s a declarative one. And what’s most important is understanding what it is trying to solve (mostly not styling elements with tag’s style). Which is what Tailwind is replicating.

Tailwind may help you in some cases, but not because of a defect in CSS. It’s like using an ORM, then past a certain treshold, you find yourself doing (badly) SQL but in $language.



I still don't understand how not naming things is a benefit over inline styles? With inline styles, instead of class="bg-blue" you'd write style="background-color:blue" and then you could remove an entire build step and an entire dependency because the browser already supports this.


You can override bg-blue with a more specific selector or a user stylesheet, which you cannot do with inline styles.


That; and also adjacent selectors, pseudo elements, media queries, variants, dark mode handling, state handling (hover, focus, etc.), and much more.


Configuration. Inline styles are direct style Implementations in your html, tailwind is an abstraction that lets your configure and refactor easily. I can say from experience, being in charge of developing a large product that was bought and merged into a larger corporation, using tailwind from the start allowed us a refactor our app’s design within 1 day instead of it being several weeks worth of work.

And as a bonus it provides best practices in css scaffolding of a product design (typography, grid, colors)



So how does that work exactly?

For instance now I have class some-button to make the button blue. Next week I‘m told make them yellow.

It’s a change in one class

What would be the equivalent in Tailwind?



It’s less about replacing blue with yellow, which means overhauling design. My example was when your style system includes several color spectrums - primary, secondary, accent, grey, dark, light.

Your components are styled using these spectrums - button.color-primary-500.bg-grey-300

When you want to change the colors globally it’s extremely simple.

Same with paddings and margins.



You use components, e.g. react, and replace the `bg-blue-500` class with `bg-yellow-500` in your button component.


So that's exactly the same as using the CSS style directly. The way you've described it, Tailwind provides no benefit whatsoever.


So tailwind needs to be used with some kind of library or framework and not vanilla HTML and JS?


It's possible to use with vanilla, but probably not a good experience. You want either components or at least a templating system where you can break things down into reusable parts.

It's somewhat similar to raw HTML vs something like PHP, you can have thousand of HTML files, but if you wanna change something common (say the header) it's not fun with thousands of individual files.

Lastly you can combine Tailwind with regular css classes

    .btn-primary {
      @apply bg-blue-500 px-2 py-1;
    }
but at that point I'm not sure how much you are gaining by using Tailwind


HTML already has a button component. How is this better than creating a root CSS style for buttons using CSS variables to abstract the colors?


For this contrived example it isn't better. I was very sceptical of tailwind before I tried it, but in certain scenarios it's nice. I think it shines if you are already using a component focused development process. As others have said you don't need to come up with class names for every thing you want to style. Rather than cross-reference between js/html files and css files everything (structure, style, and interactivity) is in one place. You also don't need to care about specificity.

Personally I think it gets a bit mad when you start wanting to do :hover, :active and media queries, but you can still use classes (using the @apply directive) for that if you wish.



The root style is global to one app, the component may be used in many different apps.


But you can use CSS rules to override variable values for more specific selections. So you can define a global --primary-button-color at the root, apply it to every button, then override --primary-button-color in, say, `tool-container`.


mobile selectors, "group" selectors, hover styles... the list goes on and on. like all things, it depends on how your workflow. if you have a super defined hierarchy and naming scheme you can reference then sure, centralize all your CSS. if you have many components and multiple people working on them sometimes it's better to separate everything out and enforce with a guide.

i can't tell you how frustrating it is to open a component and have no idea what you're looking at because you worked on the thing months ago, or you change one thing in your centralized CSS and have no idea what the side effect are. with tailwind i can see exactly the styles i'm looking for.

FOR ME, works better to have a core style file and then move everything to something like tailwind per component for maintenance.

tired of seeing the same simplistic arguments against utility frameworks. if you can't see the merits of it then you obviously aren't working on projects that need that, but don't criticize it blindly. it's not for lack of CSS knowledge.



The thing is, when you are doing CSS properly, you will "anchor" your selectors appropriately. What I mean is the following: Ltes say you got some "component" or whatever you want to call it, and have a button in it, that is special in some way. Of course you are not gonna write "button a {someproperty: specialvalue}". You should be writing the selector as specific for that component in this case, for example "my-special-component button a {...}". If the design is implemented thoughtfully, then most of the problems people claim to have with CSS are simply non-existent.

Like "side-effect" you mention. That can only happen, if the design is implemented reusing parts of other design definitions, where they are not meant to be reused. Any other side effect would be intentional. For example button text color and paragraph text color. If one wants them both to change, when one of them is changed, then one reuses the style definition, but probably in most cases one does not, and therefore has separate definitions and therefore has no silly side effects, even after a few months not looking at the project.



yeah i'm just tired of making the same argument over and over. for what it's worth i've been doing CSS "properly" since the time when that site was a thing.

back in the backbone days, now vue/react and before tailwind this is EXACTLY what we did, scope the styles down to the component, then layer it on top of the global styles. so sure, .my-selector a is specific to that component.

the "side effect" happens when your app starts to span 100s of components and you need slight variations for everything. you're telling me you can assure me that none of your master global classes contain any design definitions that could not possibly be reused? i'm calling bullshit. it's like saying your backend 100% never has any duplicated functions.

so with that out of the way, let's say you do get your global styles like 90% of the way there. so in each component you scoped it down. now lets say for one button you had to adjust the margin a bit, or another the styling is somewhat diff. multiply this by 100s of different components.

tell me now how me opening a file, seeing "button variation-class-1 variation-class-2", then going down into the component