I'm sorry to tell you, but you completely miss the point of using Tailwind.
So, perhaps it's the other way around, that Tailwind is simply not a good tool at scale.
A) CSS / Tailwind: lots of little 'atomic' classes describing individual visual properties. Easy to understand, easy to customize, but slow to read, slow to get started, with plenty of stuff to learn
B) CSS frameworks / Tailwind-based components: fewer classes declaratively describing the component's role (eg 'btn-primary'). Quick to get started, elegant to read, but prone to abstraction leakage and trickier to bend to your own exact specifications
There's always been a need for both kind of tools for different projects and there will always be, in the same way that e.g. network programming may involve anything from bit-banging commands to high-level protocols.
(And you will often go back and forth in the same project: you quickly crap out your first draft using prebuilt components, then it turns into a serious project and you start actually investing time in design and twiddle with the individual properties, and eventually it grows to a large project where you now have to go back to components again for the sake of maintainability, but this time it's your own components with your own accumulated set of properties.)
Over the years CSS frameworks kept improving, but CSS was much slower to do so - although it acquired flexbox, grid, etc., the language limitations stayed, and they were bad enough to e.g. spawn SASS/LESS out of a genuine need for better maintainability.
Tailwind takes all the stuff that was added to CSS over two decades, like media queries, and makes it part of the core nu-CSS language design. Tailwind saw a ton of hype and adoption because all the developers who had always wanted to go the (A) road now had a well-designed set of simple classes they could use with a lot less hassle, plus a bunch of developers who had adopted (B) because it was the road that had all the momentum suddenly realized that they probably wanted to use (A) once it was made less painful.
Many of the flame wars between "pro-Tailwind" and "anti-Tailwind" people were actually disagreement over whether to take the A or the B road.
Using @apply, header classes, or component projects like DaisyUI somewhat resembles using a CSS framework like Bootstrap, but by building on top of Tailwind it means that, when your project or resources grow and you want to move from (B) to fully customizing your style in (A), you will be able to write your individual little graphic touches in Tailwind instead of plain CSS.
I mean, look at the syntax for something like this:
[--scroll-offset:56px] lg:[--scroll-offset:44px]You linked to a very interesting TS library above, vanilla-extract, and you can probably see that what it does is very similar to what Tailwind does, only plugging into 'tsc' instead of PostCSS? Eg. https://vanilla-extract.style/documentation/styling/#media-q...
Regarding the QoL, it seems more to me that now Tailwind discovered that they have to support arbitrary CSS as well as every new feature, so they have to manipulate their DSL to fit all of that into their current syntax, ie class names, even if it doesn't fully fit. I'd rather just use CSS at that point, if I'm cramming a bunch of stuff into a class name.
I still love using it, and will continue to do so. This isn't enough to stop me from using it. Normally I try to avoid this, and abstract the repeated bundle of tailwind classes in a component instead (it can be a container component or just some useful utility component to avoid having to repeat the same group of classes too much). This can have its own drawbacks, because having too many custom components that you need to remember to use in given situations (which is effectively how most design-systems would work anyway) makes the codebase less approachable.
And even still, we'll end up using the above trick (referencing a group of classes bundled into a property of an object somewhere else) from time to time, as well as the obvious option of just repeating classes as necessary. Referencing classes from an imported object is annoying too, because it breaks intellisense.
I'm honestly not sure what a better solution is though, because Tailwind has really sped things up for me compared to CSS/Sass/Chakra/Material.
No worry about how you reference things or static-ness etc and the final output can be flattened down to just div + css even across module boundaries or when nesting multiple times.
The fact is @apply is there and if we're using it and there's enough push-back, I don't see why the Tailwind team wouldn't listen to that or create a workable upgrade path for those who wish to continue to use it.
So use the tools you have - don't avoid it just because the core team dislike it. They can't remove it in the version you have installed today (unless they have some magical way to reach into your computer/server)
I keep being surprised that noone bring this up in these discussions.
I think this is the main reason why Tailwind took off so fast. The frontend tooling world forgot the majority of its users.
BUT, then what if you want to add some kind of special behavior to your button that involves subcomponents, e.g. a loading state that conditionally renders a spinner inside the button? Or you want to provide convenience props like rendering an icon before or after the button text? Then a class is not enough.
If you're building a design system/component library, none of these options are simple and there are always tradeoffs.
Perl, maybe, but not APL. CSS version of APL would let me style my personal site and blog in less characters than it took me to write this comment :).
> const headerClasses = [(list of Tailwind classes here)];
> <header className={...headerClasses}>...</header>
Why wouldn't they extract the header as a higher-order component? That would make more sense even without Tailwind, and I haven't heard anyone in the Tailwind community advocate against that.not true, separating components by concern can save you a lot of fiddling with memoization
Sort of, except instead of context switching between CSS, HTML, JS and your programming language, you can now remove the CSS entirely. Less context switching is good.
I'm a Tailwind fan and I don't see a problem with that pattern for some cases. Obviously there are better ways to organize that should be preferred in general, but it's fine to do that here and there.
<button
bg="blue-400 hover:blue-500 dark:blue-500 dark:hover:blue-600"
text="sm white"
font="mono light"
p="y-2 x-4"
border="2 rounded blue-200"
>
https://windicss.org/features/attributify.htmlBut I think the author's main gripe was that component abstraction was made difficult with Tailwind when you want to customize the component from the outside, by dynamically altering the styles through props (as often needed for contextualization in design systems), and not just no-prop components like Tailwind suggests: https://tailwindcss.com/#component-driven
These days I recommend learning CSS really well and then using Vanilla Extract (https://vanilla-extract.style), a CSS in TypeScript library that compiles down to raw CSS, basically using TS as your preprocessor instead of SCSS. For dynamic styles, they have an optional small runtime.
They have a Stitches-like API called Recipes that's phenomenal as well, especially for design systems, you can define your variants and what CSS needs to be applied for each one, so you can map your design components 1-to-1 with your code:
import { recipe } from '@vanilla-extract/recipes';
export const button = recipe({ base: { borderRadius: 6 },
});Impressive that OP still is using ReasonReact, I thought it was all but dead after ReScript.