[css-scoping][selectors] `:root` should resolve to `:host` in shadow trees
https://drafts.csswg.org/selectors/#the-scope-pseudo
Currently, if used in regular CSS but outside an @scope rule, :scope resolves to :root. However, this is not super useful within shadow CSS. :host would be a lot more natural.
This would be a breaking change, but I’d wager the prevalence of :scope outside @scope in shadow CSS is so low that we can still make it.
This means the same CSS can be used within Shadow DOM to style the component, as well as using @import ... scope(...) to style light DOM elements.
This means the same CSS can be used within Shadow DOM to style the component, as well as using @import ... scope(...) to style light DOM elements.
This is indeed an annoying pain point right now when trying to share styles. While you can write :where(:host, :scope, :root), it's cumbersome and I believe this isn't currently supported in Safari (bug or unspec'd?).
Separately and for the same reason could :root resolve to :host in a shadow tree?
Separately and for the same reason could
:rootresolve to:hostin a shadow tree?
YES!
Actually, that’s all we need. Since :scope resolves to :root outside @scope, if :root resolves to :host, by proxy :scope also resolves to :host. I’ll rename the issue.
Highlight pseudo-elements inherit custom properties from :root. Does this mean that in shadow dom they will be inherited from the host?
Even if resolving to :host is more natural, right now authors can choose :host vs :root.
If both :root and :scope behave as :host, then authors will lose the ability to target the actual root.
So maybe just changing :scope but not :root would offer more flexibility.
Edit: or maybe just let :root match the host, while in :host-context(:root) it refers to the actual root (or host's host)?
Highlight pseudo-elements inherit custom properties from
:root. Does this mean that in shadow dom they will be inherited from the host?
Seems reasonable.
Even if resolving to
:hostis more natural, right now authors can choose:hostvs:root. If both:rootand:scopebehave as:host, then authors will lose the ability to target the actual root. So maybe just changing:scopebut not:rootwould offer more flexibility.
Not sure that kind of flexibility is something authors need though, given that :root is meaningless in shadow roots.
Edit: or maybe just let
:rootmatch the host, while in:host-context(:root)it refers to the actual root (or host's host)?
That seems reasonable.
Edit: or maybe just let :root match the host, while in :host-context(:root) it refers to the actual root (or host's host)?
Hmm, this is basically the same as allowing :scope to point to different things depending on where it appears in a selector, which I'm pretty sure we explicitly decided to avoid in the past (@mirisuzanne). Although :host-context() might be enough of an "explicit tree-context switch" that it's OK after all ...
So maybe just changing :scope but not :root would offer more flexibility.
I think this move makes more sense, since :scope is already intended to be the "root in some context".
:where(:host, :scope, :root)
If we let :scope match the host, you'd only need :scope for that.
I support making :scope match the :host for sure. I do think :host-context(:root) is a very explicit opt-in if we do want to make the change to :root as well. That change makes sense to me on first glance.
As @LeaVerou said, :root doesn't match anything currently in a shadow tree so the change would be to make it do something useful when sharing a stylesheet also used in the main document.
A relevant use case would be to define a series of custom properties on :root, and you might want to ensure these are defined as they are in :root for a given shadowRoot if you know that they may have been reset via inheritance.
Regarding :host-context(:root), I think it's unfortunate to rely much on something like this since we're in a bad spot on :host-content where Webkit has refused to implement it.
The CSS Working Group just discussed [css-scoping][selectors] `:root` should resolve to `:host` in shadow trees, and agreed to the following:
RESOLVED: Have have `:scope` resolve to `:host` rather than `:root` in shadow tree
The full IRC log of that discussion
<emilio> q+<bramus> TabAtkins: lea mentioen that you the `:scope` resolves to `:root`. within shadow roots tha tis not useful, shoudl resolve to `:host`
<emilio> ack TabAtkins
<bramus> … because `:root` never matches
<astearns> ack TabAtkins
<bramus> … that way you can use same styles inside and outside shadow tree
<astearns> ack emilio
<bramus> emilio: compat concerns
<bramus> … there is usefulness to have `:root` and `:host` be different
<dbaron> I'm unsure whether we want the possibly-implied change to the way highlight pseudos work.
<bramus> … e.g. in the firefox fronted we use SD a lot
<bramus> … and the stylesheets end up being global styles too
<bramus> … dont want those to be overridden on very shadow root
<bramus> TabAtkins: would not overrid ehwen defined on `:root`
<bramus> … was wrong: proposal is to have `:scope` resolve to `:host` elem in shadow tree, rather than root.
<bramus> emilio: makes more sense
<miriam> +1
<bramus> PROPOSED RESOLUTION: Have have `:scope` resolve to `:host` rather than `:root` in shadow tree
<bramus> RESOLVED: Have have `:scope` resolve to `:host` rather than `:root` in shadow tree
<bramus> TabAtkins: (missed)
<dbaron> TabAtkins: there was a second issue raised about changing :root but as emilio points out that might cause problems
<bramus> emilio: extra q: does this affect parent selector? (&)
<bramus> … which is defined to match `:scope`
<bramus> TabAtkins: yes, i suspect it will
emilio: extra q: does this affect parent selector? (&) … which is defined to match :scopeTabAtkins: yes, i suspect it will
Currently, this does not match in a Shadow DOM targeted style:
:host {
&.red {
background: red;
}
}
Based on this change, will this match?
:scope {
&.red {
background: red;
}
}
~top & should resolve to :scope?~ future:
top & in light dom: :scope -> :root
top & in shadow dom: :scope -> :root -> :host
& {
color: red;
&:hover {
color: blue;
}
}
This allows you to write the same css in the light dom and shadow dom for sharing