News for hackers. Stuff that matters.
Re:Signals for Tailwind CSS (styling based on ancestor state... by tptacek on Saturday August 31, 2024 @04:32PM (#41411731)
Well, yes, that is more or less the idea of Tailwind right?
Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @05:04PM (#41411958)
I think OP is pointing to the irony of using an increasingly verbose and overly complex wrapper API that makes it utterly painful to maintain styles "just" to avoid learning css, which is regarded by many developers as confusing or hard to learn, but is actually much more accessible, legible and maintainable than what Tailwind had become by now.

I might be reading a lot into this remark and mostly relying my own opinions here though.

But throughout the years I've been seeing how CSS is universally met with insane prejudice and expectation of it being "too complicated" or painful to learn, and Tailwind being praised as the solution while actually being much more verbose and obfuscated, and time after time leading to irrecoverable tech debt, utterly illegible markup, and complete dead ends whenever style needs any kind of refactoring.

Now that CSS is maturing and getting tons and tons of new features, Tailwind lags behind and keeps introducing more weird workarounds and hacks to be able to support all of it. The line in OPs comment is an example of it literally coming down to writing mutilated CSS selector statements directly to html attributes just to be able to do some of the stuff `:has()` enables, and creating horribly illegible markup and non-reusable styles in the process ...

Imho the original issue leading to "stylesheets are a pain" was never really CSS itself (at least since module 4 & custom props), but rather the top level management of tokens in a design system to not have to memorize colors and sizes etc -- Tailwind is simply collaterally fixing the right problem with the worst approach thinkable, but keeps being hailed as a holy grail by people who lack understanding of this.

Re:Signals for Tailwind CSS (styling based on ancestor state... by llamaimperative on Saturday August 31, 2024 @05:09PM (#41412001)
Perhaps the point of Tailwind isn't to obviate the need to learn CSS. Which seems obviously true to me, given that if you don't know CSS you can't really use Tailwind very effectively.

There's definitely a 0.1% long tail that's tricky with Tailwind (like this), but 99.9% of app styling is so ludicrously fast in Tailwind as compared to writing raw CSS.

Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @07:45PM (#41412918)
It definitely isn't, my point is that it seems to be largely is misunderstood as this being it's main purpose.

Tailwind is unquestionably accelerating drafting up a custom UI, and also makes this much more approachable for webdevs unaccustomed to CSS

The pitfall of declaring all your styles as strings of shorthands in html atts also might never hit you if your UI doesn't get too complex and/or never needs refactoring - but it hits hard if your codebase had grown to a certain scale over the years, and you suddenly need to change or refactor larger parts of the UI

Re:Signals for Tailwind CSS (styling based on ancestor state... by paulddraper on Sunday September 01, 2024 @07:43PM (#41421283)
> There's definitely a 0.1% long tail that's tricky with Tailwind (like this)

That's the first example on the README.

(Though perhaps the author of this project did a bad job as choosing a representative example of Tailwind code.)

Re:Signals for Tailwind CSS (styling based on ancestor state... by llamaimperative on Monday September 02, 2024 @12:06PM (#41426593)
Right, because it's a usecase that (allegedly) warrants a totally separate package/plugin. Not much CSS is dependent on reading ancestor state.
Re:Signals for Tailwind CSS (styling based on ancestor state... by aidos on Saturday August 31, 2024 @05:12PM (#41412024)
I disagree with the main motivations and benefit. For me it’s always been about being able to handle hover states etc without having to leave the local context where I’m working. I don’t think anyone can really write tailwind without understanding css.
Re:Signals for Tailwind CSS (styling based on ancestor state... by franga2000 on Saturday August 31, 2024 @05:37PM (#41412200)
Adobe Brackets had an interesting solution to the context switching problem. There was a keybind, I think CTRL+E, that would let you edit all the styles that apply to the current element in a kind of inline sub-editor. It was quite neat and I haven't seen it done in any other editor.
Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @07:48PM (#41412933)
if the styles only concern the context you work on, this could easily be done with vanilla scoped inline styles

If those declarations are relevant to multiple components within your codebase, then you'll still need to leave the context when your styles are inlined and therefore declared in multiple places

Re:Signals for Tailwind CSS (styling based on ancestor state... by aidos on Sunday September 01, 2024 @03:34AM (#41415022)
No. That’s the point of tailwind. You can include things like hover states. Inline css hits a roadblock there and you’re forced to go out to a style tag. Then you have to start naming things. Then you risk conflicts.

That’s the problem tailwind solves.

Re:Signals for Tailwind CSS (styling based on ancestor state... by spankalee on Saturday August 31, 2024 @05:44PM (#41412250)
You didn't have to leave the local context if you use very local stylesheets. Scoped CSS like shadow DOM, plus CSS text right with your component, helps a lot with this.
Re:Signals for Tailwind CSS (styling based on ancestor state... by wruza on Saturday August 31, 2024 @06:52PM (#41412646)
Style attribute lacks a selector (“color:red” vs. “.comp {color:red}”), forbidding the most useful use case. Shadow dom is an inspection nightmare used only by a few progressive web purists. Style.css is an untyped incoherent spaghetti. There’s no really good place for an element style in current implementation.
Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @07:50PM (#41412943)
op is not talking about style atts, but referring to nesting inline `<style> @scope { ... }</style>` to declare vanilla css in the scope & context of specific DOM nodes
Re:Signals for Tailwind CSS (styling based on ancestor state... by wruza on Sunday September 01, 2024 @03:52AM (#41415083)
Isn’t it a “limited availability” feature? Why would they use it?
Re:Signals for Tailwind CSS (styling based on ancestor state... by paulddraper on Sunday September 01, 2024 @07:54PM (#41421318)
Yeah, but `@scope` is only if you don't want to support Firefox.
Re:Signals for Tailwind CSS (styling based on ancestor state... by spankalee on Monday September 02, 2024 @03:08PM (#41427990)
No, in taking about the native scoping you get with shadow DOM, which is awesome and not an "inspection nightmare".
Re:Signals for Tailwind CSS (styling based on ancestor state... by tptacek on Saturday August 31, 2024 @05:08PM (#41411993)
Thanks! This is helpful.
Re:Signals for Tailwind CSS (styling based on ancestor state... by troupo on Saturday August 31, 2024 @05:15PM (#41412052)
CSS took 20 years to begrudgingly incorporate the most useful features of SASS, and these are still not wide spread or (like nesting) have become available barely a year ago.

CSS is verbose, repetitive, error-prone, and requires insane workarounds to keep it manageable.

There's a reason why SASS has been nearly a de-facto industry standard, and why abominations like BEM exist.

Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @05:45PM (#41412254)
SASS and LESS have their place, but they are tooling, not replacements

The time it took for CSS to progress like this although is on Browser vendors, not on the language - lots of recent features that seem utterly late to the game have existed for years and years, but had to be deemed "unsafe" to use because of Safari, Firefox and other browsers that lag far behind the standard.

And honestly, the critique you throw at CSS is all the more true for Tailwind actually, and imho only stands the test for _badly written_ code, which holds true for any language in any domain.

And regarding why BEM exists: it's just a flavour of naming convention for your "API", nowhere mandated by CSS itself. Its main purpose is to optimise paint performance and keeping your component naming lean and transparent. You may very well simply write expressive and specific queries instead of defining naming conventions for your components.

But I'm unsure if we talk about the same things in the end, cause none of those points get any better with Tailwind, rather the opposite.

Re:Signals for Tailwind CSS (styling based on ancestor state... by troupo on Sunday September 01, 2024 @02:48AM (#41414850)
> because of Safari, Firefox and other browsers that lag far behind the standard.

I could've guessed there would be a blame game.

No, neither Safari nor Firefox lag in web standards. Moreover, it was Firefox (IIRC) which figured out how to do nesting safely.

However, even beyond nesting there multiple other things that lagged in browsers. CSS Scope was completely derailed by Chrome's push for Web Components, and had to be solved by other tools.

Nesting, mixins and a lot of other tools were long seen by all browser vendors as "unnecessary and better solved by tools". So yes, SASS isn't a replacement but there are reasons why it existed and was a nearly de-facto standard in tooling for so long. And that reason isn't "CSS is so great".

> And regarding why BEM exists: it's just a flavour of naming convention for your "API", nowhere mandated by CSS itself. Its main purpose is to optimise paint performance

No, it's main purpose is to try and close the gap in CSS: CSS is/was absolutely horrendously unsuitable for any type of componentized code. And BEM was an attempt to solve that at the process/naming level.

No, BEM isn't mandated by CSS. However, it exists because CSS had literally no tools to support the use cases BEM was aimed at.

> But I'm unsure if we talk about the same things in the end, cause none of those points get any better with Tailwind

I didn't even talk about Tailwind. I was directly addressing your claims about CSS.

CSS was never great.

Re:Signals for Tailwind CSS (styling based on ancestor state... by koito17 on Saturday August 31, 2024 @04:39PM (#41411778)
I've understood the point of Tailwind to be two things:

1. Allow styling to co-exist with your DOM layout rather than separate files

2. Provide a ready-to-use style system built atop utility classes

Emphasis on "utility classes". This is what makes Tailwind different from e.g. Bootstrap.

I don't think the point is to avoid writing CSS. The point is to write CSS in a way that allows it to be co-located with DOM layout, so that UI components can become self-contained pieces of code.

Re:Signals for Tailwind CSS (styling based on ancestor state... by threatofrain on Saturday August 31, 2024 @04:51PM (#41411856)
If anything this puts a slightly higher burden on the dev because you're still always responsible for the underlying CSS, now you just have to be aware of how the utility classes map to CSS.
Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @06:20PM (#41412470)
I think this is precisely what I am ranting about.

These two usecases is what makes Tailwind so useful and accessible for drafting stuff up, but also bear the pitfalls of tech debt to actually maintain and iterate the design system of complex ui systems

What irks me is that so many people seem to be utterly unaware of this intent, and rather regard Tailwind as some sort of "better css", on the basis of not knowing much about CSS

But a truly good and flexible design system needs all of it in the end:

- a top layer config that allows definition and maintenance of design tokens

- an intermediate layer of abstracted presets to ensure portability and maintainability of design system specific patterns

- a lib-level layer of utilities to avoid having to force one-off declarations like the layout of a specific view into either of the other abstractions (Ex: "search results as 3 column grid on desktop" is not a design system concern, it's neither a "style", nor relevant to any other components or visual styles)

When it comes to keeping styles & markup together, this has always been possible with simply using `<style>` tags in your templates or components. The performance impact is absolutely negligible IRL, and any leakage or selector naming concerns have also become a none-issue with `@scope`

Don't get me wrong, Tailwind has the RIGHT IDEA! It solves to top level layer of managing the design system, which also is the main reason for it's success imho

The big issue is that it is constantly being used the wrong way, @apply which would allow for proper abstraction of component styles is largely being ignored, and thus instead of forcing utility into superfluous class bloat like it's common in framework-less vanilla CSS integrations, most of it's users rather force the intermediate abstraction into the utility-only layer, producing unmaintainable garbage markup and utterly illegible and repetitive style declarations.

And to get back to my original point: This comes imho from the widely prevalent fallacy that Tailwind ought to replace the "traditional way" of writing styles, and failure to understand that it is meant to merely extend on it & utility classes should be employed in moderation and for specific purposes in design-systemized UIs

Re:Signals for Tailwind CSS (styling based on ancestor state... by gedy on Saturday August 31, 2024 @06:23PM (#41412486)
> These two usecases is what makes Tailwind so useful and accessible for drafting stuff up, but also bear the pitfalls of tech debt to actually maintain and iterate the design system of complex ui systems

Tailwind is really rotten for complete design systems, (I'm not just talking about an app's theme like colors and fonts)

Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @07:52PM (#41412950)
this is exactly the point, using it for ALL the styles was always a horrible idea -- and never it's intention (i think)
Re:Signals for Tailwind CSS (styling based on ancestor state... by djbusby on Saturday August 31, 2024 @04:51PM (#41411857)
And when the CSS is "inline" via classes vs raw style then you get consistent padding (p-4) vs some things that vary and are hard to update theme-wide (padding: 8px).

It's basically putting a bunch of CSS into "vars" or macros.

Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @05:50PM (#41412289)
Exactly my point: it provides an interface to manage design tokens, instead of having to think about those constantly and litter your code with magic values everywhere.

But the way this systemisation is integrated throws away most of the advantages. What good is having "p-4" abstracting "8px", when you then repetitively hardcode the alias all over your markup instead of defining individual, reusable and easily maintainable classes?

Re:Signals for Tailwind CSS (styling based on ancestor state... by modal-soul on Saturday August 31, 2024 @07:15PM (#41412759)
In order to get value out of Tailwind, you need to be using a templating language that lets you create reusable components. So in this way, you are not repeating the 7 classes each time you need a card, but just using the component.

This is also makes "zombie CSS" a thing of the past, since the resultant CSS file that tailwind generates is based solely on what is in use.

Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @08:24PM (#41413099)
isn't this exactly what CSS is meant to solve originally?

Write a class & map it to the relevant component or DOM node in a template, so you only have a single source of truth to maintain the styles of that component.

Writing the explicit style declarations directly to the DOM nodes themselves is precisely what _prevents_ portability and reusability.

The perf issue of "zombie css" is seldomly an issue in my experience: if it really impacts your load time or perf, you can still easily serve subsetted stylesheets at build or request time

If the perf impact is negligible, you might in turn profit from serving all the css at first, since it will be cached and accelerate subsequent request or rehydration

Removing unused CSS is mainly a concern for _inline_ styles, since the bloat of the initial HTML might impact FCP and repaints/reprocessing once additional stylesheet are loaded.

... which ironically also means that adding truckloads of utility classes to every DOM node might introduce quite some initial load & paint performance implications aswell, depending on your app.

It might even be interesting to benchmark if a stylesheet with a bunch of "zombie css" really has more perf impact than serving a minmaxed css file, but requiring dozens of classes on every other DOM node to be processed for painting

it's not a file size game in the end, the amount of selector statements & DOM nodes they might apply to has much larger paint perf impact than a few kb of unused gzipped text

Re:Signals for Tailwind CSS (styling based on ancestor state... by gedy on Saturday August 31, 2024 @06:22PM (#41412478)
> Emphasis on "utility classes". This is what makes Tailwind different from e.g. Bootstrap.

Just FYI that Bootstrap 5+ has really good utility classes: https://getbootstrap.com/docs/5.3/utilities/background/

This plus their component classes makes Bootstrap a lot more practical for most needs imho, and without needing some build step.

Re:Signals for Tailwind CSS (styling based on ancestor state... by paulddraper on Saturday August 31, 2024 @04:51PM (#41411849)
The last paragraph sounds like CSS-in-JS
Re:Signals for Tailwind CSS (styling based on ancestor state... by krsdcbl on Saturday August 31, 2024 @06:45PM (#41412612)
Tbh I never really understood the reason for the existence of css-in-js either.

Just do vanilla `<style> @scope { /* your component styles without any naming bloat ... */ } </style>` nested in the markup/jsx, and optionally leave merging any of that for perf optimisation to some rudimentary build tooling or hydration

But also: I do see the QoL benefits of colocating styles & markup, but it has drawbacks aswell: it prevents you from being able to reuse design systems across different applications/codebases, and increases maintenance complexity and tech debt as soon as you introduce utility classes or any styling rules that aren't hard-tied to a singular component. Both issues scale painfully fast with the complexity of your App/UI, and impact Tailwind-based UIs even more in my experience.

Re:Signals for Tailwind CSS (styling based on ancestor state... by paulddraper on Sunday September 01, 2024 @12:35AM (#41414327)
For one thing, Firefox.
Re:Signals for Tailwind CSS (styling based on ancestor state... by muratsu on Saturday August 31, 2024 @05:03PM (#41411949)
This is what most people want + some utility functions & good default variables (for colors etc).

If you're doing relatively straightforward things, tailwind is super easy to work with and that's why a lot of people prefer it today. Having it inline makes it easy to digest (both for humans and LLMs) until things get complicated.

I see this similar to using javascript in your project. When you start fresh on a new project, typescript can be seen as a bottleneck, slowing you down. As project evolves your needs also evolve and other solutions might be a better choice.

Re:Signals for Tailwind CSS (styling based on ancestor state... by koito17 on Saturday August 31, 2024 @05:08PM (#41411990)
CSS-in-JS solutions like Emotion provide something close to that! But they come with some drawbacks (e.g. needs careful setup for server-side generation, spends a few CPU cycles translating to CSS, breaks memoization unless one uses deep object comparison or stores the style data separately from the component).

CSS modules provide a great alternative if one is willing to write CSS in separate files. Otherwise, Tailwind has provided a smoother experience than CSS-in-JS for me.

Re:Signals for Tailwind CSS (styling based on ancestor state... by meiraleal on Saturday August 31, 2024 @05:39PM (#41412212)
Not really. The example is worse than CSS in many ways and the idea of tailwind wasn't to be worse than CSS.