Shadow DOM is a failed API. If someone was out there pushing document.links and being like “Oh yeah, it’s super-quirky but it’s a standard.” You’d look at them like they’re crazy for not using document.querySelector instead, since querySelector is also a standard and a better thought out one that is more flexible. Shadow DOM was an attempt to do ten different things, and now we have better standards compliant ways of doing almost all of them. There’s not really a good reason to master this totally janky API when there are better alternatives.
I think the proposed ARIA changes are good because there should be better ways to connect things than using IDs, but it’s worth noting that unique IDs are pretty much trivial to setup in React, Vue, etc. (Alpine even has a neat ID helper builtin.) You create some global variable as “my-app-” + counter and every time you use it you do counter++ and you always get unique IDs out of it. Again, I’d like a better API for it, but this is simple enough and works. That Shadow DOM can’t do the same because they mistakenly semi-isolated but not really parts of the DOM is so much the worse for Shadow DOM.
Good article. The first conclusion of not using shadow DOM was my conclusion too. I try to push towards using native UI controls where possible, styling them when I can, or not. A lot of web tech bites off more than it can chew, entire frameworks bubble up to hide the complexity only for it to rear its ugly head when you need to debug our go outside their guidelines (which you always seem to do).
Reminds me of the CSS-in-JS crowd: inline styles break avoiding the unsafe-inline directive for styles. Their solution, have your build tool do hashes and provide nonces for every inline style in the code base. This tied you to a framework, a specific build tool, and got you to the point where you couldn’t understand the build anymore. The alternative was right in front of you: just use CSS… in CSS.