> naming things is hard
This is an argument that would have held more weight for me before I started using BEM. Naming your CSS should be exactly as hard as naming your component, and no harder.
Is your React/Vue/Svette component named "GenericButton"? Congrats, that's your class name. Got some markup under it that you need to style and you're worried about name intersections? Don't be; "GenericButton__whatever". You never need to worry about collisions again, they just don't happen. And you never need to worry about naming, you just use the same names that you're using in your Javascript/Typescript.
----
To me, I look at Tailwind, and it feels like taking a bunch of React components and saying "no, don't separate those out into hooks and helpers, inline all of it." People say that Tailwind is about locality of style, but I just don't see it. Locality of style, component-based CSS -- you do that by using components and by scoping your CSS to those components. You can do that with normal CSS. Heck, there are even libraries that will get rid of the cascade if it becomes a problem.
I'm told that the reason Tailwind often ends up looking like spaghetti code is because you're supposed to be using more helpers with it and that you can make it reusable. Sure, I buy that. I buy that it can be made reusable and composable. But say that you make it reusable and composable -- part of that process is going to be naming things. It's going to be deciding what to name your helpers and your shared styles you want to use everywhere.
So I don't know, maybe there's something I'm missing. I agreed with a lot of the criticisms of "semantic" CSS and I might have been really receptive to Tailwind at some point (I do think using element names in CSS is usually bad practice), but then BEM happened and I realized, "hey, you can just name CSS after the component you have it attached to, and then suddenly all of these problems go away and it becomes way easier to debug because you always know exactly what to search for in the codebase and where to look to adjust every class."
And yeah it's more verbose and the double underscores look a little ugly, but come on, we're comparing it to Tailwind. Having your markup look a little bit ugly obviously isn't a dealbreaker.
I'm trying not to be dismissive of Tailwind in part because a lot of people use it and like it, and I felt dismissive about BEM as well before I started using it. So I keep on using Tailwind when I run into it, I keep on waiting for it to click. It hasn't yet. Maybe I'm just not seeing it or not using it right but I'm never tempted to use it when I don't have to.
----
Edit: I will add to this, you want to talk about coupling CSS to Javascript then one of the cool things about BEM styling is that your generated output documents your Javascript/Typescript.
When I look at an app that's using BEM, and I see part the HTML that I want to change, even if I've never looked at the codebase before in my life I know exactly what to grep to get to the HTML and exactly what file I need to change. If somebody wants something added to a footer, I know what filename to search for to get that footer, I know the full list of every component that's inside that footer just by looking at the HTML. I know how the Javascript code is organized just from the HTML. And that makes it so much easier to just think about individual components without having to worry about understanding an entire application.
In comparison, every time I look at an app with Tailwind, I'm struck by how utterly useless the generated HTML is for doing any kind of debugging -- both debugging style and debugging the HTML/Javascript.
Because it turns out that having every component name in code mirrored to your class list and tied to your styles makes it really easy to cross-reference everything.