- From: François REMY <francois.remy.dev@outlook.com>
- Date: Mon, 12 Jan 2015 23:47:13 +0100
- To: "'Tab Atkins Jr.'" <jackalmage@gmail.com>, "'Anne van Kesteren'" <annevk@annevk.nl>
- CC: <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 FWIW, I agree with this analysis. I think the objectives here are better served by using a Shadow DOM or a CSS+DOM-rewriting tool adding a class on each elements based on the stylesheets that should apply on them (this could be easily achieved using grunt). That being said, a process similar to the grunt one could be allowed in CSS, too. @disable-mode(name) .dark-dom; @enable-mode(name) .dark-dom > .light-dom; @toggle-mode(name) .toogle-light-dom; @mode(name) { /* rules here only apply for elements whose 'name' mode is enabled */ } I don't think this is a great idea, though. It adds new complexity to CSS (a second matching phase) which I don't think is worthwhile.
Received on Monday, 12 January 2015 22:48:04 UTC