[csswg-drafts] [css-scoping] [selectors] :scope and DocumentFragment / ShadowRoot (#7261)

emilio has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-scoping] [selectors] :scope and DocumentFragment / ShadowRoot ==
Relevant spec sections are:

 * https://drafts.csswg.org/selectors-4/#the-scope-pseudo
 * https://drafts.csswg.org/selectors-4/#scoping-root
 * https://dom.spec.whatwg.org/#dom-parentnode-queryselector
 * https://drafts.csswg.org/css-scoping/#host-element-in-tree

If I read the specs correctly:

 1. `Element.querySelectorAll(":scope > *")` returns all the direct descendants of the given element. This is interoperable behavior and not ambiguous.
 2. `Document.querySelectorAll(":scope > *")` ought to work and return only the root element (the scoping root would be the `Document` node, and it has only one child, which is the document element). Browsers are interoperable here but not following this reasoning. Instead, `:scope` is the root element (so such a query returns the `<head>` and `<body>` elements, usually). 
 3. `DocumentFragment.querySelectorAll(":scope > *")` ought to work and return the children of the fragment, because the scoping root is the fragment, and is a virtual scoping root. This works in Blink, but not in Gecko and WebKit (`:scope` is undefined, so it falls back to the root element of the document, so it never matches anything).
 4. In style sheets, `:scope` is always the root element of the document, because there's no defined scoping node, and that's the fallback. That's Gecko and WebKit's behavior. Blink in shadow trees considers the shadow root a `:scope` (https://crbug.com/1272434), but `:scope` doesn't match the shadow host directly like `:host` does.

This is all very unfortunate and inconsistent. It's clear that the spec is wrong for the `Document.querySelector` case, IMO (though the spec doesn't define `Document` as a potential "virtual" scoping root, it follows that if such should work for `DocumentFragment` it ought to work for `Document` as well?).

We should probably agree on the non-interoperable cases. If we wanted to make `:scope` behave consistently for `Document` and `DocumentFragment`, we ought to probably either:

 * Make all direct children of the fragment match `:scope` (rather than what the spec currently says / what Blink does), or.
 * Leave the scope node undefined (which is what WebKit / Gecko does), so it always matches the root element as a fallback.

For the stylesheets case, I think WebKit and Gecko follow the spec and the spec is somewhat reasonable. We have `:host` for shadow trees, and even tho defining `:scope` is possible, it might be a bit tricky, depending on how we define the above.

Thoughts?

cc @tabatkins @lilles @anttijk

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7261 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Sunday, 8 May 2022 21:17:19 UTC