w3c / csswg-drafts

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

[css-selectors-4] Clarification needed for scoped selectors (§3.3 and §8.6) #5712

Open danburzo opened 3 years ago

danburzo commented 3 years ago

Hi, I'm having a bit of a hard time understanding the terminology in CSS Selectors Level 4 regarding scoped selectors:

In particular, I find it hard to follow what is meant by scoping root vs. :scope elements in the absence of examples pointing out which is which, in something like elem.querySelector('...').

I'd love to provide more detailed suggestions on the content of the two sections, but I feel I need a mental model of what's meant in them. Could someone explain, in layman's terms, what a scoping root and a :scope element are for the commonplace DOM methods (matches/querySelector/querySelectorAll)? (I can offer my confused interpretation of things, but I doubt that would help at this point).

Loirooriol commented 3 years ago

So elem.querySelector('...') is defined in https://dom.spec.whatwg.org/#dom-parentnode-queryselector, it runs scope-match a selectors string '...' against elem. This basically sets elem as the scoping root when matching.

And since the :scope elements are not explicitly specified, but the selector is scoped and the scoping root is the element elem, then elem matches :scope (and nothing else matches).

It's basically the same for querySelectorAll: https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall

For matches, the element is used as the :scope element but not as the scoping root.

danburzo commented 3 years ago

@Loirooriol Thank you for the reply! Just to make sure I got that, I'm going to paraphrase your explanation:

The DOM methods Element.querySelector(s)/Element.querySelectorAll(s) use their Element instance (this) as a scoping root.

:scope elements is a mechanism for methods invoking the match a selector against an element algorithm to override the meaning of the :scope selector, which would otherwise fall back to the scoping root, if any (:root if there's no scoping root).

In contrast to querySelector/querySelectorAll, matches() and closest() don't scope their matches to this (most obvious for closest, which needs to reach up the DOM tree), but they do want :scope to match this, and not :root.

If that's the case, my top suggestions (both of them IMHO):