It's really frustrating to be talking with someone about Tailwind and CSS, and realize that not only do they not know what "cascading" means, they never even considered the concept might be useful in the context of a stylesheet.
And none of this really violates DRY, your unit of reuse has shifted from a CSS class to a framework component. There's nothing precluding you from using an approach like DaisyUI if stock Tailwind has too much repetition for your taste.
This is what CSS classes were made for. Of all of the arguments in favor of Tailwind, this is the one that drives me battiest. Say what you will about CSS, but "give a name to a re-usable set of styles for a component" is pretty much as fundamental as you can get.
> And none of this really violates DRY, your unit of reuse has shifted from a CSS class to a framework component.
Sure, sure. except for the inline styles everywhere. And the fact that everything is literally being repeated all over the place. But other than that, no repetition!
> There's nothing precluding you from using an approach like DaisyUI if stock Tailwind has too much repetition for your taste.
...and now you have three problems.
That brings with it the problem of naming a thousand things in a consistent way that everyone on your team needs to understand and remember, otherwise you end up with tons of duplicated classes, parallel systems, and bike shedding. Have we, as an industry, not felt this pain often enough yet? Do we really need to keep banging our head against the wall to figure out it does hurt?
> Sure, sure. except for the inline styles everywhere.
There are no inline styles when using Tailwind. There are references to variables from the design system.
> And the fact that everything is literally being repeated all over the place.
If you find yourself repeating the same sequence of classes, it's time to create a component in your frontend framework if you use one, or a Tailwind utility class. And even if you just copy-paste the same class strings all over the codebase, transport compression will eliminate that pretty much entirely.
Of course. It's obviously better to have 10,000 different names that are all loosely, but not exactly the same as the CSS property they're trying to represent.
The client still has to decompress it and waste processing power parsing all the repeated text.
It’s like my grandparents worrying about immediately switching off their LED ceiling lamps when they leave a room - meant well, but utterly meaningless.
I mean, come on, there is usually tons of context and team internal language for the new thing to build and to talk about it, distinguishing it from the old thing that was already built.
And if that's too hard, then allow the design department to name the things they design and notify them about any clashes. They must have a design language anyway.
Like yes, CSS by itself is extremely powerful, but I see no reason why you should feel beholden to use all of its features simply because they're there.
> Sure, sure. except for the inline styles everywhere. And the fact that everything is literally being repeated all over the place. But other than that, no repetition!
Well, instead of repeating inline class names everywhere, you end up with CSS properties repeated everywhere. Not really seeing the difference.
Erm...what now? That's so off-the-wall that I can't even wrap my head around your meaning.
Are you trying to argue that because, say, a conventional CSS file has "border:1px" in multiple places, this is somehow equivalent to the Tailwind approach of making a "b1p" class that captures the same thing [1], and plastering it across your templates?
Because a non-abusive application of CSS would actually just put that border property in a semantic class like ".widget" or something, and sure, you'd have multiple "border:1px" declarations across all of your CSS files, but that's irrelevant, because you're not trying to reconstitute every style inline from pseudo-properties.
[1] I am making this example up for illustrative purposes.
.widget {
border: 1px;
}
...
const Widget = () => (
<div class="widget"></div>
);
vs const Widget = () => (
<div class="b1p"></div>
);
You keep saying this is an abuse of CSS and that's not how it was meant to be used, but why is that so important?Obviously, a real application will have more than one css property. Also, your widgets will share styles, usually in a fairly obvious hierarchical way. And your designers will want them all to be consistent.
In this world, it’s far easier to remember that a widget is “.widget”, and that “.rounded-widget” is for the round version of that”, than it is to remember that the former concept is “.b1p .m5 .ib .xyz .pdq .foo” while the latter is “.b1p .m5 .p2 .br10 .xyz .bar”
It’s like the difference between
app_name = "Foobar"
print(f"Welcome to {app_name}")
print(f"Learn how to use {app_name}")
and print(f"Welcome to Foobar")
print(f"Learn how to use Foobar")
Any good programmer knows why the former is better.Yes. And as 30 years of CSS show, it's not enough.
> Sure, sure. except for the inline styles everywhere. And the fact that everything is literally being repeated all over the place.
It's not repeated all over the place, because in your codebase you have a single place where component A is defined. A single place where component B is defined etc.
I don't see you complaining about having to repeat the same CSS properties (padding, margin, display etc. + responsive styles + hover/disabled etc.) for half of the components when writing vanilla classes.
And when this is pointed out you’ll usually get replies that just hand wave it away as not a problem, as if things like BEM were invented for no reason.
But sure, like most tools, it starts with understanding how it works.
Sooner or later it deteriorates.
Whenever i have written CSS/TailwindCSS which was unproblematic to extend it was when i literally switch thinking to use least amount of properties and let the page flow.
Whenever i see tons of css i know it’s brittle and will cause hours of wasted time down the line to fix something which already should have been fixed.
That seems like a false dichotomy. I'm a huge fan of locality (both in software engineering and in physis) but you can also "localize" your styles by scoping them appropriately. (Modern frontend frameworks typically do that automatically for you at the component level.) There is no need to use Tailwind for that.
I meant physics of course!
No, I don’t think that’s the case at all.
I think that was true at the beginning. But Tailwind is quickly approaching the multi-headed hydra it was trying to replace.
Tailwind, on the other hand, attempts to address a different set of problems, but I am not getting into that here -- other comments have summarized it well.
It works until doesn't, and you'll have to figure out what's going on with your code.
It gets really easy to lean on class-based CSS and use a `<div>` for everything instead of ever learning what a semantic element is.
And that contributes to other bad habits, like writing a bunch of JavaScript to define behavior that could just be natively handled by your browser.
A weird personal irony is that because no employer has ever asked me to directly write CSS, what's actually made me better at CSS is JavaScript -- namely that my understanding of selector logic has improved a lot after picking up Web scraping.