You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[cssom-1] Expose resolved selectorText on CSSStyleRule #10246
On a CSSStyleRule you can get the selectorText that returns the textual representation of the selector.
With CSS nesting, this value has become somewhat less useful as it doesn’t represent the full selector.
While an author can use script to compute the flattened selector by manually walking the .parentRule to the top and then doing the checks + replacements for &, it would be nice if this was built into the platform. That way, an author can directly use it in something like document.querySelectorAll.
I’m thinking of a property named flattenedSelectorText or fullSelectorText.
We use flatten for naive replacements. This does a simple replacement of & with the parent selector. The result is a mangled selector that won't match the same elements but this is useful for static analysis. (e.g. how many type selectors did the author write in source?)
We use resolve to get a full selector that would also match the same elements. (e.g. what is the specificity of this selector?)
If there was a specification for this action we should have similar behavior between tooling and browsers.
it could have limits and throw when those limits are exceeded
This seems very fragile. I would prefer a different design that doesn't suffer from this, e.g.
document.querySelectorAllWithNesting("a, b","& c, & d","& e, & f")
instead of
document.querySelectorAll("a c e, a c f, a d e, a d f, b c e, b c f, b d e, b d f")document.querySelectorAll(":is(:is(a, b) c, :is(a, b) d) e, :is(:is(a, b) c, :is(a, b) d) f")
The current OM does represent the full selector; the & selector is not evaluated by substitution, but rather refers directly to the elements selected by the parent rule.
Understanding the use-cases better would be useful. If it's about making it easier to select the same elements in qSA() as a particular style block, we can cater to that more directly. @Loirooriol's suggestion (multiple selector arguments, representing nested selectors) might work, for example. But also, you seem to be suggesting that authors would be willing to crawl the OM and obtain a selector directly off of the CSSStyleRule - how serious were you about that in particular as a use-case? Because we could also, say, allow qSA() to take a CSSStyleRule directly, and return the same set of elements the rule matches, if that code pattern seems realistic.
Romain mentions some preprocessor uses, notably determining the specificity. Is there more?
preprocessor uses, notably determining the specificity. Is there more?
For preprocessors or author tooling in general? No, all variations on the same theme :)
e.g. determining if &::before {} would be valid, which it might not be if & represents something like ::after. This is essentially the same problem as calculating specificity.
You need to do something with & to be able to give feedback on what the author wrote.
This is true for any indirection (e.g. var())
The current OM does represent the full selector; the & selector is not evaluated by substitution, but rather refers directly to the elements selected by the parent rule.
Sorry, should have said “flattened” or “resolved” selector.
Understanding the use-cases better would be useful. If it's about making it easier to select the same elements in qSA() as a particular style block, we can cater to that more directly.
That’s my specific use-case indeed.
You seem to be suggesting that authors would be willing to crawl the OM and obtain a selector directly off of the CSSStyleRule - how serious were you about that in particular as a use-case?
It came up when writing a (rough) polyfill for ident() + attr() for this demo but admittedly not all authors write that type of stuff.
Another use case is doing an analysis of the loaded CSS (nesting depth, layers extraction, etc.) with userland code.
changed the title [-][cssom-1] Expose nested selectorText on CSSStyleRule[/-][+][cssom-1] Expose resolved selectorText on CSSStyleRule[/+]on Oct 1, 2024
Activity
romainmenke commentedon Apr 24, 2024
This would be very useful!
For all things PostCSS, Stylelint, ... we also need to determine the full selector and I created a helper for this : https://github.com/csstools/postcss-plugins/tree/main/packages/selector-resolve-nested#readme
The wording we use is a bit different : https://github.com/csstools/postcss-plugins/blob/main/packages/selector-resolve-nested/docs/selector-resolve-nested.md#functions
We use
flattenfor naive replacements. This does a simple replacement of&with the parent selector. The result is a mangled selector that won't match the same elements but this is useful for static analysis. (e.g. how many type selectors did the author write in source?)We use
resolveto get a full selector that would also match the same elements. (e.g. what is the specificity of this selector?)If there was a specification for this action we should have similar behavior between tooling and browsers.
bramus commentedon Apr 24, 2024
Great distinction between flattened and resolved. Given this, what I suggested would better be named
resolvedSelectorText.Loirooriol commentedon Apr 24, 2024
This seems vulnerable to a "billion laughs attack".
romainmenke commentedon Apr 24, 2024
It is, but given that it is a script API it could have limits and throw when those limits are exceeded.Edit : It is not.
This would serialize selectors with
:is()Loirooriol commentedon Apr 24, 2024
This seems very fragile. I would prefer a different design that doesn't suffer from this, e.g.
instead of
This doesn't avoid the problem.
romainmenke commentedon Apr 24, 2024
You are right, it makes it slightly smaller.
But still quickly explodes in cases like this one :
tabatkins commentedon Apr 25, 2024
The current OM does represent the full selector; the
&selector is not evaluated by substitution, but rather refers directly to the elements selected by the parent rule.Understanding the use-cases better would be useful. If it's about making it easier to select the same elements in qSA() as a particular style block, we can cater to that more directly. @Loirooriol's suggestion (multiple selector arguments, representing nested selectors) might work, for example. But also, you seem to be suggesting that authors would be willing to crawl the OM and obtain a selector directly off of the CSSStyleRule - how serious were you about that in particular as a use-case? Because we could also, say, allow qSA() to take a CSSStyleRule directly, and return the same set of elements the rule matches, if that code pattern seems realistic.
Romain mentions some preprocessor uses, notably determining the specificity. Is there more?
romainmenke commentedon Apr 25, 2024
For preprocessors or author tooling in general? No, all variations on the same theme :)
e.g. determining if
&::before {}would be valid, which it might not be if&represents something like::after. This is essentially the same problem as calculating specificity.You need to do something with
&to be able to give feedback on what the author wrote.This is true for any indirection (e.g.
var())bramus commentedon Apr 25, 2024
Sorry, should have said “flattened” or “resolved” selector.
That’s my specific use-case indeed.
It came up when writing a (rough) polyfill for
ident()+attr()for this demo but admittedly not all authors write that type of stuff.Another use case is doing an analysis of the loaded CSS (nesting depth, layers extraction, etc.) with userland code.
LeaVerou commentedon Apr 25, 2024
Agree that the OM needs to provide both. If
selectorTextproduces the full/resolved selector, thenlocalSelectorcould produce the local one.Loirooriol commentedon Apr 25, 2024
@LeaVerou I'm confused, isn't the current selector the same as the local one?
LeaVerou commentedon Apr 25, 2024
@Loirooriol edited
bramus commentedon Apr 26, 2024
@LeaVerou You still got it flipped, no?
selectorTextis the existing property which returns the local selector. The ask in c0 is for a new property that returns the resolved selector.[-][cssom-1] Expose nested selectorText on CSSStyleRule[/-][+][cssom-1] Expose resolved selectorText on CSSStyleRule[/+]