w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.46k stars 657 forks source link

[css-anchor-position] anchor-scope and part descendant styling #10525

Open vmpstr opened 3 months ago

vmpstr commented 3 months ago

anchor-scope is specified to limit the exposure of anchors to not go above the anchor-scope element. However, anchor-name are also tree scoped which means that an element that is exposed as a part and given an anchor-name that way is scoped to the tree scope of the stylesheet that gives it a name (outside of the shadow dom).

I wanted to clarify what happens if both of these features are in effect:

<style>
my-element::part(anchor) {
  anchor-name: --anchor;
}
</style>
<my-element>
  <template shadowrootmode="open">
    <div id="scoper" style="anchor-scope: all">
       <div id="anchor" part="anchor"></div>
    </div>
  </template>
</my-element>

Here the #scoper element is scoping all the anchors to its subtree, but #anchor is exposed as a part and is styled in the outer tree scope and is given an anchor-name there. Is that a valid anchor in the outer (or inner) tree scope?

/cc @andruud @tabatkins

andruud commented 3 months ago

This should be well defined now. Only anchor queries from within the flat-tree subtree of #scoper can "see" --anchor. So it's not visible in the outer scope, except when the query comes from another ::part(), e.g.:

<style>
my-element::part(anchor) {
  anchor-name: --anchor;
}
my-element::part(anchored) {
  left: anchor(--anchor right);
}
</style>
<my-element>
  <template shadowrootmode="open">
    <div id="scoper" style="anchor-scope: all">
       <div id="anchor" part="anchor"></div>
       <div id="anchored" part="anchor"></div> <!-- Works -->
    </div>
   <!-- But not if part=anchor was here instead. -->
  </template>
</my-element>
<!-- And certainly not from here. -->

(And also a similar case with a slotted element).

In the inner scope, --anchor is visible inside #scoper, but not outside it.

vmpstr commented 3 months ago

That's interesting. I suspect that may be a little unexpected for developers: using a web component that exposes an element as a part, but giving that part an anchor name and trying to anchor to it doesn't work because unbeknownst to the developer, the web component has an anchor-scope protecting the part

andruud commented 3 months ago

I am tempted to say that the web component author shouldn't have blocked all anchors if all anchors shouldn't be blocked.

If you're worried that this is a bad situation they will fall into accidentally, then we'll need to invent some kind of "tree-scoped all"?

tabatkins commented 1 month ago

Yeah, per the discussion in #10526 I think all should act tree-scoped; aka it only scopes anchor names with a matching tree scope. It would be weird if it was impossible to scope a specific cross-tree anchor, but possible to scope it as part of blocking all of them.

andruud commented 1 month ago

OK, that makes sense.

Agenda+ to see if we can make all tree-scoped.

css-meeting-bot commented 2 weeks ago

The CSS Working Group just discussed [css-anchor-position] anchor-scope and part descendant styling, and agreed to the following:

The full IRC log of that discussion <chrishtr> tabatkins: anchor-scope, in addition to idents, can take the keyword 'all', which scopes all names. Should this be a tree-scoped 'all'? (i.e. only applies to the current tree scope
<chrishtr> tabatkins: proposed resolution: the 'all' keyword is also tree-scoped in the same way
<fantasai> sgtm
<khush> +1, again same pattern with view-transition-group
<chrishtr> RESOLVED: the 'all' keyword is tree-scoped