6 ms·
Signals for Tailwind CSS (styling based on ancestor state via style queries)
- skeptrune 2y agoThis is really fun. SolidJS has the `classList` attribute which I use a lot in scenarios where this would work. I think a plugin like this would also be preferable so as to avoid the extra JS state code which really always feels like a cheap hack.
- paulddraper 2y agohover:[&>div]:bg-green-800 peer-checked:[&>div]:bg-green-800 Anything to avoid writing CSS
- tptacek 2y agoWell, yes, that is more or less the idea of Tailwind right?
- koito17 2y agoI'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.
- paulddraper 2y agoThe last paragraph sounds like CSS-in-JS
- muratsu 2y agoThis 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.
- koito17 2y agoCSS-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.
- krsdcbl 2y agoTbh 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.
- paulddraper 2y agoFor one thing, Firefox.
- threatofrain 2y agoIf 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.
- djbusby 2y agoAnd 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.
- krsdcbl 2y agoExactly 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?
- modal-soul 2y agoIn 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.
- krsdcbl 2y agoisn'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
- krsdcbl 2y agoI 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
- gedy 2y ago> 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)
- gedy 2y ago> 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/ 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.
- krsdcbl 2y agoI 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.
- tptacek 2y agoThanks! This is helpful.
- llamaimperative 2y agoPerhaps 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.
- decremental 2y ago
- deleted 2y ago[deleted]
- meiraleal 2y agoNot really. The example is worse than CSS in many ways and the idea of tailwind wasn't to be worse than CSS.
- muratsu 2y agoI didn't know about the @container queries, they look interesting. Having said that, I'm not a huge fan of pushing more state logic to CSS. I understand the benefits (from the github page) but pushing more text into the style string without thinking about tooling (how to debug etc) is dangerous.
- tengbretson 2y agoWrite-only code is so hot right now
- meiraleal 2y agoIt is a hype phase. Everybody adds tailwind, later everybody removes tailwind. We need to find ways to be busy anyway.
- tdy_err 2y agoTailwind has _the_ highest retention of any CSS framework ~75% YOY according to StateOfCSS surveys (2019-2024)
- meiraleal 2y agoYeah, for like 2 years? That's the hype phase. (you are talking BS, 2024 there is no data about it, 2019 there isn't also. if the stats you brought is true it would be at maximum from 2021-2023)
- montroser 2y agoTailwind is both great and terrible. The trick is to take just the good parts and not let it poison the rest. Let it make easy things easier, but don't let it take over and make the hard things impossibly difficult. Here's how to do it: use Tailwind only for layout (margin, padding, flex) and brand consistency properties like text size, line height, colors etc. Beyond that, anything that requires changing presentation based on state, embrace CSS. It was meant for this, and remains the best solution. Invest in learning CSS because it will still be here in 20 years.
- Griever 2y agoI’m a strong advocate for Tailwind, and I believe that this approach is truly effective. In my experience, this subset of Tailwind has been sufficient for every project I've worked on that used it. Moreover, I've observed that it often converts skeptics into supporters.
- krsdcbl 2y agoCurious about your expectations: Do you rely on utility classes only in your workflow, or do you split reusable patterns into "original CSS"-like @apply blocks? And how would you categorise the complexity of the Apps/UIs you build like this? I'm very interested in the specifics of successful applications of Tailwind that the maintainers keep deeming a good solution, since CSS as a whole is one of my main scopes and I've had quite some projects that where basically some variation of writing custom brand-lib frameworks for teams who embraced Tailwind at first, but in time ended up hard locked when needing to refactor or iterate their UI
- Griever 2y agoGreat question. We rarely rely on shared utility classes these days. Historically we'd end up going the @apply route, but lately we just add a new style to the root-level css file and call it a day. We may prefix it with "@layer" so that it gets tree-shaken, but that's about it. I've found that in component-driven UI, the need for these kinds of utility classes becomes less and less necessary. The utility CSS may be defined in the component, and the component is ultimately what gets reused. Could you elaborate more on the reason for your interest? I've used Tailwind to implement several well-defined design languages, and always had great success. In fact, compared to other design systems, Material for example, I found it to be far simpler to manage over time.
- wruza 2y agostyle queries As expected, they didn’t stop with :has and slowly turn it into a subturing abomination.
- inopinatus 2y agoNSFW but I just want to point out that using form validity semantics we are not constrained to telegraphing state within local element hierarchy/adjacency but can in fact toggle a binary, selectable CSS state from anywhere on a page. https://codepen.io/inopinatus/pen/vYxrOeR https://codepen.io/inopinatus/pen/vYxrOeR