Re: [csswg-drafts] Mixing :is() (or equivalent) with pseudo-elements (#9702)

> Then ideally we would disallow & except at the start of the compound? 

Well, we don't currently have that limitation, and Nesting has been out for long enough that we probably can't change that.

> It's not unreasonable to expect :hover::before here. I get that it's consistent with the "filtering" model, but this will surely be seen as your selector being silently re-ordered.

I think it is somewhat unreasonable. For any *normal* element matched by the parent rule, `:hover&` in the child rule  will mean "the same elements as the parent, but only when they're hovered", same as `&:hover`. So `::before { :hover& {...}}` should match that - the same elements as the parent rule (some ::before pseudos), but only when they're hovered, aka `::before:hover`. It's no more re-ordering than `div { :hover& {...}}` is when it desugars to `div:hover`.

If you wanted the other way, you'd need the pseudo combinator, and  you'd write `::before { :hover :> & {...}}`.

> This would then desugar to: `.foo = (&) { ... }`, `.foo = (& > .bar) { ... }`?

No, since they're no longer nesting the `&` doesn't do the right thing. The (current) limitation in the proposal is that the `(<sel>)` can only change the subject via a pseudo-element selector; otherwise it's just filtering whatever the current unit would be otherwise. That's the issue with `&, & > .bar` - it's both retaining the parent's match set *and* moving to the match set's children element (and the filtering them with `.bar`). (But see the end of this comment for more exploration of this.)

> Are there any restrictions on where lists with pseudos can appear

No. It's just another option for the `<complex-selector-unit>` production, so you can chain after it with another combinator/etc

> Can anything follow it (that is not allowed parse time today)? `.a = (.b, ::after) = .c {...}`.

Yes, that's valid, and equivalent to `.a.b.c, .a::after.c {...}`.

> Is there anything that could be improved in this proposal if we first fix that mistake (as an alternative way to access pseudo elements), and then make that form work well with nesting?

No, that's not the side that's problematic for Nesting. Nesting has issues due to our decision to keep it as purely a sugar as possible, without causing combinatorial or exponential blowup in the desugaring. That means we're limited to what `:is()` can do, and `.foo:is(.bar, * :> before)` (using the `:>` "pseudo combinator" proposal we resolved on) also doesn't do what you're wanting. (It only matches ::before pseudos that are *also* `.foo` elements, aka `::before.foo`

The problem is that, unless we introduce a third way to refer to the "subject" coming from outside the `()` list, we're stuck with one of two options: either the subject is implicitly what the `()` selectors *match* (aka the last compound matches the subject) or it's implicitly what the `()` selectors *descend from* (aka the selectors are implicitly relative).

That is, we could move the selector *into* the parentheses, and then `.foo { &, & > .bar {...}}` could desugar to `.foo (= *, > .bar) {...}`, or we could leave the selector *outside* and then `.foo { &, .bar > & {...}}` desugars to `.foo = (*, .bar > *) {...}`. But we can't do both, and `:is()` already matches the second one, so staying consistent with that seems good.

The fact that `::foo` is *not* actually using the combinator machinery rescues us slightly and makes the case I'm trying to solve work - it just leans on the fact that pseudo-elements can already change the subject of the selector between combinators.

-- 
GitHub Notification of comment by tabatkins
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/9702#issuecomment-2711875230 using your GitHub account


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

Received on Monday, 10 March 2025 21:23:56 UTC