Re: [webcomponents] Style attributes in Shadow DOM Cascade Order Proposal (#316)

Okay, bringing in a full example, as there are now four different ways styles can interact on a single element:

```html
<style id=page>menuitem { color: red; }</style>
<menu>
  <::shadow>
    <style id=content>::content menuitem { color: green; }</style>
    <content select="menuitem">
  </::shadow>
  <menuitem style="color: yellow;">
    <::shadow>
      <style id=host>:host { color: blue; }</style>
      ...
    </::shadow>
  </menuitem>
</menu>
```

We have the following principles that should be honored:

1. Style attr is "scoped" to the element. Scoped rules know better what styling should happen than "generic" outer page rules, so they should usually win. Since they're intermixed with generic rules, we need to give them an auto-win, reversible with !important. Handled by the **Scoping** cascade step.
2. Shadow styles are the opposite - "generic" rules from outside don't apply at all, so the shadow rules "win" by default. Since outer page rules intruding are special-case and intentional, we can let them auto-win against shadow rules. !important reverses this, allowing the shadow to set invariants. Handled by the **Shadow Tree** cascade step, which occurs before **Scoping**.
3. :host vs outer page is a little different. "Generic" rules from the outer doc can hit the host element, so the reasoning doesn't hold as strongly, but simplicity in handling shadow stuff dictates it should agree with normal shadow rules (plus the default/invariant dichotomy seems useful here, too).
4. ::content is the same - they intermix with "generic" rules, but simplicity in shadows, plus usefulness of the default/invariant dichotomy, suggests they agree with the normal shadow rules.

So we have:

* inline > page
* page > content
* page > host
* inline > content && inline > host (both by transitivity, and by direct application - it's from the outer page, and so wins against shadow rules)
* content <?> host

It's just ::content vs :host that we have to deal with. I don't have a strong opinion on which one should win, but it *feels* like ::content rules are similar to outer-page rules, relative to :host rules, and so they should act the same and win.

That would give us an ordering of `inline > page > content > host`.

If !important is used, on any single element it auto-wins due to the **Origin** cascade step. If everyone's important, then:

* host beats content, per the "shadow beats outer page when !important" rule in the **Shadow Tree** cascade step (assuming we decide that ::content is "outer page" relative to :host)
* host beats page and inline, same reason
* content beats page and inline, same reason
* inline beats page, per the **Specificity** cascade step.

So we have almost an opposite ordering: `host > content > inline > page`.

Does this all sound good to everyone?  If so, I'll figure out how to wordsmith the "::content is considered to be in an ancestor tree relative to :host" thing.

---
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/316#issuecomment-149735841

Received on Tuesday, 20 October 2015 23:40:33 UTC