Re: [css-scoping] Shadow Cascading

On Fri, Feb 6, 2015 at 10:11 AM, Rune Lillesveen <rune@opera.com> wrote:
> On Fri, Feb 6, 2015 at 1:13 AM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>
>> Hmm, you're right, this isn't very stable.  If you remove #3, it
>> completely changes the ordering, so that #2 sorts ahead of #1, rather
>> than at the end.  The ordering of any two declarations shouldn't be
>> affected by the presence or absence of other declarations.
>>
>> We should fix this up somehow to make things work better.  It probably
>> means adding some special cascade behavior for ::content?
>
> I don't have experience in making real web components.
>
> I don't know the rationale for handling re-distribution to shadow tree
> siblings differently from distribution to shadow trees for other
> hosts.
>
> If specificity should beat ordering for redistribution and ::content
> through different hosts, like the spec says now, why isn't that what
> you want for re-distribution through shadow tree siblings as well?

We have a similar sort of complex inter-dependencies even with single
shadow roots when some of the scopes have an ascendant/descendant
relationship in the tree-of-trees, and some not.

Example:

<style id="A"></style>
<host1>
    <:shadowroot>
        <style id="B"></style>
        <host1_1>
            <:shadowroot>
                <style id="C"></style>
                <div>
                    <content/>
                </div>
            </:shadowroot>
            <content/>
        </host1_1>
    </:shadowroot>
    <host2>
        <:shadowroot>
            <style id="D"></style>
            <content/>
        </:shadowroot>
        <inner/>
    </host2>
</host1>

Plain ::content rules stylesheets A, B, C and D may apply to <inner>.

Rules from A beats non-important rules in B, C, D because it's in an
outer scope.
Rules from B beats non-important rules in C (outer scope).
Rules from B and C beats rules in D if they have higher specificity,
but D wins for rules with the same specificity because of
order-of-appearance in the tree-of-trees.
Then, !important rules also have to be taken into account, turning
things upside down for inner/outer case.

This is mildly said complicated to implement.

It should be noted that Blink currently only tries to implement the
tree-of-trees order-of-appearance part of the cascading order in the
CSS Scoping spec, which means specificity currently trumps scope. Even
that part has bugs [1].

What I think would be simpler, both to grasp for authors(?), and to
implement, is to specify the cascading order in terms of the composed
tree.

For the example above, the composed tree path from the <inner> element
and up is:

  inner -> host2 -> div -> host1_1 -> host1

This gives a total parent/child ordering of the scopes that apply to a
given element:

  scope(D) -> scope(C) -> scope(B) -> scope(A)

If you include the shadow roots you pass through traversing the
composed tree, you end up with:

  inner -> scope(D) -> host2 -> div -> scope(C) -> host1_1 -> scope(B)
-> host1 -> scope(A)

(should work for multiple shadow roots as well)

The ordering of rules from stylesheets A-D for the <inner> element
would then be:

1. scope(D) Important
2. scope(C) Important
3. scope(B) Important
4. scope(A) Important
5. scope(A) normal
6. scope(B) normal
7. scope(C) normal
8. scope(D) normal

That means specificity will not make a rule from one shadow tree beat
a rule from another. I don't know why it currently is like that, or if
it makes sense.

[1] crbug.com/452542

-- 
Rune Lillesveen

Received on Friday, 15 May 2015 21:59:56 UTC