The cascade is a wonderful idea that has unfortunately not played out well in practice. Anyone who thinks it's just a skill issue is deluding themselves. In all my years, I've never seen CSS that (a) leverages the cascade, and (b) scales elegantly. It all breaks down past a certain point.
Tailwind has it's flaws, but it doesn't have the scaling problem.
Personally, my dream would be if inline styles supported the full CSS gamut of pseudo selectors and the child element selector. Then you'd have the admitted benefits of not needing to synchronize the two files, along with the benefit of not needing to relearn all of CSS.
Edit: it's funny, in a way, that all these developers complaining about how CSS "doesn't scale" are likely writing their Tailwind in an large scale application styled entirely via CSS. https://github.com/search?q=repo%3Amicrosoft%2Fvscode++langu...
As a trivial example, let's imagine we need to apply a border radius to an element. Without Tailwind, it looks like this:
1. I find the element I need to style
2. I look at which class it's using
3. I navigate to my CSS file
4. I scroll down until I find the selector
5. I type "border-r", then tab on the auto-complete to fill in "border-radius"
6. I type the colon character, then space
7. I think about what unit is appropriate - rems, ems, pixels, percentage
8. I think about what value is needed for the design
9. I also look around to see if this style is used elsewhere
10. If the style is used elsewhere, I think about whether I need to refactor
11. I type in the desired value
12. I type a semicolon to mark the end of the statement
13. I type cmd+s to save the css file
Here's the same example, with Tailwind: 1. I find the element I need to style
2. I type `round` and wait for the autocomplete to present my options
3. I use my arrow key to select which one I want
4. I type enter to add the desired tailwind class
5. I type cmd+s to save the html file
The Tailwind interaction path takes less than half of the concrete steps to complete. But it's even more dramatic than that, because several of the steps taken in the first example require enough thought that it breaks your workflow and takes you out of your flow state. Then you have to get back into that flow state to keep working. But this keeps happening, so you're constantly stopping and restarting. With Tailwind, I tend to find myself staying in that flow state, because as I demonstrated above, there's very little getting in my way.Normal CSS is usually worse than this too e.g. you hit save, and your edit doesn't change anything, so you have to use the web inspector to hunt down which class is overriding your style then weigh up options for how you're going to refactor while jumping between multiple files. It's exhausting when you're trying to focus on styling.
That said, I agree that this doesn't work for pseudo selectors, very unfortunately, and I wish it would.
1. I find the element I need to style
2. I add/edit the inline style={{}} attribute I have for it by typing `sty<TAB>{borrad<TAB>`
3. I add a value
VS: 1. I find the element I need to style
2. I add/edit the className attribute
3. I pull up the tailwind documentation to find how to type the CSS I already have memorized in their DSL (I know some Tailwind by heart, but wayyyyy more CSS)
4. I wait for it to load
5. I scroll down to find the version of the class name that I need
6. I go back to the editor and add the class.
Also a very common flow for me is to edit the CSS directly in the browser, it's a much faster devloop than the fastest live reload server. In that case it's far easier to just copy from the `changes` view into the CSS than go through and remap everything from CSS into Tailwind.