Re: Shadow tree style isolation primitive

> On Jan 12, 2015, at 4:10 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
> 
> On Mon, Jan 12, 2015 at 3:51 PM, Ryosuke Niwa <rniwa@apple.com> wrote:
>>> On Jan 12, 2015, at 2:41 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>>> On Mon, Jan 12, 2015 at 2:14 PM, Ryosuke Niwa <rniwa@apple.com> wrote:
>>>>> On Jan 12, 2015, at 1:28 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>>>>> 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.
>>>> 
>>>> Another alternative.  We can add a host language dependent mechanism such as an element or an attribute to "end" the current isolation, just like insertion points in a shadow DOM would.
>>>> Better yet, we can provide this mechanism in CSS. e.g.
>>>> 
>>>> @isolate foo integrates(bar) {
>>>> ...
>>>> }
>>>> 
>>>> @isolate bar {
>>>> ...
>>>> }
>>>> 
>>>> (I'm not proposing this exact syntax. We can certainly do better.)
>>> 
>>> Yeah, something like that would work, but it also means you need to
>>> account for all the things that might want to be isolated in your
>>> component.  That's relatively clumsy.
>> 
>> Examples?  Are you talking about DOM APIs such as querySelectorAll and alike?  Then, please refer to my other reply [1] in which I listed use cases that involve no author scripts.
> 
> ? I didn't mention DOM APIs.  I'm referring back to the example you're
> replying to - if you use a <bar> element inside your <foo> component,
> and you know that <bar> has isolation styles, you have to specifically
> call that out inside your <foo> styling so that it (a) is shielded
> from your foo styles, and (b) is able to pick up the global definition
> for bar styles.  This is relatively clumsy.  Some of the other
> solutions attach the "I want to be isolated" information to the
> element itself more directly, so you don't have to worry about what
> you put inside of yourself.

This is no more clumsy than defining an insertion points in shadow DOM.  Or am I misunderstanding you?

>>>>> 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.
>>>> 
>>>> Let's not conflate style isolation with isolation of DOM subtrees.  They're two distinct features.  Even though I do agree it might be desirable to have both in many important use cases, there are use cases in which we don't need subtree isolations.
>>> 
>>> I'm not trying to, I'm pointing out that "style isolation", as a
>>> concept, seamlessly blends into "DOM isolation" as you move across API surfaces.
>> 
>> I don't see any connection between the two.  Many of the use cases I listed [1] require us to have DOM isolations.
> 
> I listed a number of APIs in the text you're responding to, all of
> which may or may not want to pay attention to style isolation,
> depending on the use-case.  I'm not saying you necessarily need DOM
> isolation for any given use-case.  I'm saying that there are a lot of
> APIs that query or walk the DOM, and whether they should pay attention
> to a "style isolation" boundary is a question without clear answers.

I don't understand what you mean here.  As far as I know, there are only two sensible options here:
Style isolation implies DOM subtree isolation in all DOM APIs
Style isolation doesn't affect DOM APIs at all

Shadow DOM does 1.  I'm suggesting that we need a mechanism to do 2.  It's not terrible if we introduced @isolate to do 1 and also provided shadow DOM to do 1.  In that world, shadow DOM is a syntax sugar around @isolate in the CSS land with DOM API implications.

- R. Niwa

Received on Tuesday, 13 January 2015 00:19:19 UTC