I’ve found what you said to be completely untrue unless you’re totally lazy. If you’re building up a bunch of components, the tailwind classes are mainly within the basic components.
In the first example of vanilla extract, it uses exact px measurements which already demonstrates it’s not geared to solve one of the primary selling points of tailwind (using config as a constraint to reduce mental overhead when building things).
And have you had to work on hundreds of components that you had to refactor before? It's a write only language.
> I’ve found what you said to be completely untrue unless you’re totally lazy.
Ah yes, the laziness argument. Let's not blame our tools but ourselves for the tools are always good and righteous. If only those darn C programmers weren't so lazy writing their memory leaks.
> And have you had to work on hundreds of components that you had to refactor before? It's a write only language.
Once you know the syntax of Tailwind you can jump into any codebase and instantly know what’s going on. With “standard” CSS you’re forever jumping between components and class definitions.
Once you know the syntax of CSS properties you can jump into any codebase and instantly know what’s going on. With Tailwind you’re forever jumping between components and figuring out what that one long line of class names is actually doing.
> With Tailwind you’re forever jumping between components and figuring out what that one long line of class names is actually doing.
Only if you already have no clue what CSS is. If you know CSS and can’t figure out what a given tailwind class does, then I don’t know if anyone can help you.
That said, I do often feel that I might as well just write the css directly. Writing tailwind feels like another translation layer.
Your last paragraph is precisely what my point is. I simply don't understand why people like the indirection. Sure, it feels amazing to clap together a few classes and not have to think about naming them, until you later find that you don't know what the hell a given div is and have to spend a bunch of time parsing the one long line of Tailwind classes. If you try grouping the Tailwind classes using @apply for readability, congratulations, you have reinvented CSS classes, except with a DSL on top.
When I come back to a bit of code I haven't looked at for a long time, I find the class names I set on the individual elements extremely helpful, like comments that never go out of date. I can immediately orient myself and know which classes to look at (I use scoped/namespaced classes; not like BEM which is too dependent on HTML structure, just a namespace with the element class, like .Banner-icon).
I've never fully committed to TailwindCSS, but I have tried out my own utility classes on a smaller scale, and I found myself having to parse the entirety of the code to figure out what was going on.
My preference now is a mix of utility classes for super basic things that would be tedious to set a class on, and custom classes for everything else. Especially if media queries are involved, because good lord is that ever tedious to do with utility classes. If I find myself setting more than 2-3 utility classes on an element, I usually end up moving that to a CSS class for one reason or another. I don't define the utility classes until I need them, and I really don't use very many.
That's a good way to do it personally, and I might start taking that approach too. The Tailwind syntax for some of the more complex stuff is appalling.
One of my most-used utility class is "reset". Default styles are great, but they often get in the way, so I'll throw this on an element whenever I want to start from a blank slate, alongside other utility classes or a custom class. This can significantly cut down on the length of my CSS files, as well as make them much less brittle and less dependent on the HTML structure, because I don't need to repeatedly undo default styles in every rule I write. My scoped CSS files are typically under 100 lines, even for somewhat complicated things.
You mean the readability of "p-2 bg-red-500 text-lg font-medium" or "i-dont-remember-what-this-class-does"?
I'd argue the readability in Tailwind is better. Tailwind is highly indicative of what it does and doesn't waste time when it comes to consistency.
The only real argument is that it adds extra length to the class attribute, but then again, it doesn't cause issues like finding the same class in 50 different CSS files or not having any auto-completion.
> You mean the readability of "p-2 bg-red-500 text-lg font-medium" or "i-dont-remember-what-this-class-does"
No, I'm pretty sure he means the readability of "absolute bottom-0 text-sm md:text-base text-white leading-relaxed tracking-tighter transition-all duration-300 ease-in-out m-3 md:m-4 px-6 md:px-8 py-4 md:py-6 opacity-0 w-full", as opposed to a single well-named class such as "image-caption".
Yeah, it's bgcolor="#30312c" all over again. (One thing I like about Tailwind though is that at least it enforces some kind of grid and design tokens, but you can (and should!) easily reproduce it with CSS variables.)
Well at least I won't have to have 2 split windows just to know what 'image-caption' is and the tailwind class you wrote, perfectly readable and understandable.
If long class names aren't your thing, then sure, use CSS, but I'd rather save time and have understandable code than maintain those CSS classes like "image-caption".
> since you yourself don't want to maintain your code in the future apparently.
Well, I don't appreciate the snarky comment, quite honestly. But okay, I'll assume you have had more experience than me, and you've managed things I haven't, have a good day.
> Well at least I won't have to have 2 split windows just to know what 'image-caption' is
> I'd rather save time and have understandable code than maintain those CSS classes like "image-caption".
Sorry, but the snarkiness was in your comment first, and when you said you didn't want to maintain those classes, that's exactly what it sounded like to me, that, well, you didn't want to maintain said code. If you had a different point I'd be happy to hear it.
No, one is a restricted subset of the other, and that means you can better reason about a less expressive language. This is basically what you would have with a non-Turing complete language vs Turing complete one.
Subsets and DSLs can often be worse than the language they're supposed to replace, and moreover, you need to learn a new proprietary language on top of that. There is no need for me to write Tailwind classes when I can just write their equivalent properties in CSS instead.
To quote you from another thread in this discussion:
> I've often found that people who are in the frontend don't properly learn CSS and just hack it together. That was me too for a long while which is why I hated it. Then I started learning it from first principles and it makes a lot of sense. Now I can build whatever I need in plain CSS classes.
So sometimes people just... misunderstand or use the tool wrong?
I have, yes. It’s fine and no more annoying than css, styled or whatever else. If anything it’s easier because there’s consistent and constrained bunch of classes you can use.
Then just use CSS at that point, since the classes literally just map onto CSS properties anyway (and sometimes not even, since they have to spend time to make new, or even older, rules work). That's what I don't get about Tailwind, at its best it's as good as CSS, but oftentimes stuff like SCSS, CSS-in-TS etc are simply better.
> Then just use CSS at that point, since the classes literally just map onto CSS properties anyway
CSS is definitely a write-only language. I've yet to see anyone understand CSS in a large system and refactor it. You end up with dozens and hundreds one-off classes and overrides everywhere.
So, the same as Tailwind then? That's also why I'd consider Tailwind a write only language, except with CSS you at least have the chance of organizing it properly.
With Tailwind you have a consistent set of classes scoped usually per component. Thos p-x, m-x, and others don't change from component to component or from project to project.
Hell if I know what `.chip-text__content` is, how it's different from `.icon-button__content`, why it interferes with my CSS, and what other 15 CSS classes I need on top of that to make it work.
I think there is a disconnect between what I'm talking about regarding CSS and what everyone else is. Yes, BEM and global styling is unmaintainable, I agree with you there. However these days even with Tailwind their approach is to componentize. In the same way, I can just use CSS modules with no global styles and get the same benefits of scoped styling like Tailwind provides without having something else break as a result of what I use in the current component. However, if you're using HTML without a JS framework, Tailwind can be superior to BEM and global styles, but still not as much as CSS modules, CSS-in-TS, and the like, due to maintainability concerns.
> However, if you're using HTML without a JS framework, Tailwind can be superior to BEM and global styles, but still not as much as CSS modules, CSS-in-TS, and the like, due to maintainability concerns.
How are you going to maintain consistent values across components such as spacing colors etc? Those tend to grow to the size of Tailwind
Every design system I've come across contains any combination of:
- rigid inflexible components that need complex overrides even for the simplest cases
- multiple classes with seemingly innocuous names like "col col-8" that get increasingly obtuse and one-off like "uxg-menu-header uxg-avatar-hero-block uxg-avatar" [1] or "fas fa-fw fa-bell pf-c-alert pf-m-info pf-c-alert__title" [2]
- multiple often contradicting css variables (esp. colors)
- ... i'm missing something else, but it's late here and my brain doesn't work ...
In the first example of vanilla extract, it uses exact px measurements which already demonstrates it’s not geared to solve one of the primary selling points of tailwind (using config as a constraint to reduce mental overhead when building things).