- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Mon, 12 Jan 2015 13:28:43 -0800
- To: Anne van Kesteren <annevk@annevk.nl>
- Cc: "www-style@w3.org" <www-style@w3.org>, WebApps WG <public-webapps@w3.org>
On Fri, Jan 9, 2015 at 5:40 AM, Anne van Kesteren <annevk@annevk.nl> wrote: > I'm wondering if it's feasible to provide developers with the > primitive that the combination of Shadow DOM and CSS Scoping provides. > Namely a way to isolate a subtree from selector matching (of document > stylesheets, not necessarily user and user agent stylesheets) and > requiring a special selector, such as >>>, to pierce through the > boundary. > > This is a bit different from the `all` property as that just changes > the values of all properties, it does not make a selector such as > "div" no longer match. > > So to be clear, the idea is that if you have a tree such as > > <section class=example> > <h1>Example</h1> > <div> ... </div> > </section> > > Then a simple div selector would not match the innermost div if we > isolated the section. Instead you would have to use section >>> div or > some such. Or perhaps associate a set of selectors and style > declarations with that subtree in some manner. It's probably feasible, sure. But I'm not sure that it's necessary, or that browsers will go for it. Using a shadow root as the isolation boundary is *really convenient*, because it's a separate tree entirely; the fact that outside rules don't apply within it, and inside rules don't apply outside, falls out for free. Let's assume we did it, though. We'd have to have some mechanism for defining an isolation boundary, and denoting whether rules were "inside" or "outside" the boundary. This sounds like an at-rule, like: @isolate .example { h1 { ... } div { ... } } Now, a problem here is that you have a conflict between nesting isolated things and specifying isolation. Say you have <foo> and <bar> elements, both of which need to be isolated. You'd think you could just write: @isolate foo { ... } @isolate bar { ... } But this won't work! If you have markup like <foo><bar>...</bar></foo>, the <bar> there is inside the <foo>'s isolation boundary, so the @isolate rule can't find it. You'd need to *also* nest the "@isolate bar" rule (and all its styling rules) within the foo one, and vice versa. The effect of this on *three* mutually isolated components is, obviously, terrible; let's not even mention trying to use multiple modules together that weren't explicitly designed together. Alternately, say that it does work - the @isolate selector pierces through isolation boundaries. Then you're still screwed, because if the outer page wants to isolate .example blocks, but within your component you use .example normally, without any isolation, whoops! Suddenly your .example blocks are isolated, too, and getting weird styles applied to them, while your own styles break since they can't cross the unexpected boundary. Basically, trying to smuggle private state into a global declarative language is a bitch. So, CSS is out. We can't reasonably do this within the confines of CSS application. It needs to be handled at a different layer. We could do it in HTML, potentially - some new global attribute that creates a styling boundary that prevents outside styling from targeting anything inside. Then you can just use standard <style scoped> to apply your own styles within the boundary - as long as the scoping root is inside the boundary, styling is allowed. But that means you have to add an attribute to every element that uses this styling boundary, and move your style info into inline scoped blocks. That's annoying. :/ Let's check out JS. If you can mark some elements as always being styling boundaries, then whenever they're constructed, whether manually or via the parser, they'll get the right mechanics automatically. And since this is JS, it shouldn't be too hard to say "always attach this stylesheet to the element whenever it gets created", or perhaps introduce some explicit ability to do this in the platform. This last one, though, is pretty much exactly Custom Elements, just with the children staying in the light tree rather than being moved into a shadow tree. But keeping them in the light tree has complications; it means that everything in the platform needs to be made aware of the isolation boundary. Should qSA respect the isolation boundaries or not? Depends on what you're using it for. What about things that aren't CSS at all, like getElementsByTagName()? That's equivalent to a qSA with the same argument, but it's not a "selector", per se. Manual tree-walking would also need to be made aware of this, or else you might accidentally descend into something that wants isolation. Shadow DOM at least gives an answer to all of these, by putting the elements in a separate tree. You don't need to think of every one individually, or deal with inconsistent design when someone forgets to spec their new tree-searching thing to respect the boundary. So, do you still think it's worth it to try to subdivide the functionality further? I think it's packaged in a reasonable way at the moment. ~TJ
Received on Monday, 12 January 2015 21:29:31 UTC