In Lists, we've resolved that ::before and ::after can be set to "display: list-item", thus generating markers. However, per Selectors grammar, it's not valid to then write a selector like ol::before::marker
. (You can stack pseudo-classes after your pseudo-element, but not more pseudo-elements.)
This seems unfortunate; if a ::before can generate a marker, you should be able to style that marker.
Additionally, I know that WebKit-derived browsers, at least, do allow pseudo-element stacking, to handle styling some of the UA-specific pseudo-elements.
So, we should change Selectors grammar to allow stacking multiple pseudo-elements in a single compound selector. (Individual grammar restrictions will still restrict what sort of stacks are valid; ::before::before
will be an invalid selector, just like ::before:invalid
is invalid today even tho ::before:hover
is valid.)
Since certain pseudo-classes are reasonable to apply to either of the pseudo-elements in the stack, the two need to be arbitrary interleavable. (For example, ::before:hover::marker
.) This gives us a grammar of:
<compound-selector> = [ <type-selector>? <subclass-selector>*
[ <pseudo-element-selector> | <pseudo-class-selector> ]* ]!
The CSS Working Group just discussed Need to allow stacked pseudo-element selectors in the grammar
, and agreed to the following:
RESOLVED: Generic selector grammar allows stacking pseudo elements and classes. Only certain combos will be made valid, by default everything is invalid
The full IRC log of that discussion
<dael> Topic: Need to allow stacked pseudo-element selectors in the grammar
<dael> github: https://github.com/w3c/csswg-drafts/issues/3876
<dael> Rossen_: Is TabAtkins on?
<TabAtkins> Will be in a sec
<dael> fantasai: I can take it
<florian> I did not check that TabAtkins did the grammar correctly (I assume he did), but I support the intent.
<dael> fantasai: There were some cases where we had pseudo elements that are pseudo elements of pseudo elements. One is the marker of a before pseudo if that's set as display:list-item
<dael> fantasai: Selectors grammar only allows one in the grammar. We'll have to relax to allow this. Proposal is do it same as pseudo classes applied to pseudo elements. It's generically allow, but disallowed except for certain whitelisted combinations
<dael> fantasai: The generic grammar needs to allow forthe stacking. Proposal here is to do that for pseudo elements so one can allow another to stack after
<dael> amelia: Really a need to make the whitelist or defined at individual level. It could be a valid that doesn't match anything. Example is invalid that doesn't match anyway and wouldn't when on a before or after.
<amelia> s/match anyway/match non-form elements anyway/
<dael> fantasai: Reason to do is b/c at some point in future might allow some combos, but not sure which will become reasonable. better to make them invalid now and only the ones that make sense now are valid. When another combo is reasonable in the future we can say it's now valid and meanssomething.
<dael> fantasai: Don't want a selector that's valid now but matches nothing but 5 years from now it starts matching a bunch of stuff
<dael> Rossen_: Sounds reasonable
<dael> Rossen_: Other points?
<Rossen_> s/whitelist/allow-list/
<dbaron> sounds reasonable to me too, though I'm not sure I could extract all that fro mthe issue
<dael> Rossen_: +1 to dbaron comment. Thanks for making it clear fantasai
<dael> Rossen_: Objections to accepting the issue?
<dael> fantasai: Prop: Generic selector grammar allows stacking pseudo elements and classes. Only certain combos will be made valid, by default everything is invalid
<dael> Rossen_: Objections?
<dael> RESOLVED: Generic selector grammar allows stacking pseudo elements and classes. Only certain combos will be made valid, by default everything is invalid
Yeah, this is also necessary because of ::part(โฆ)
and ::slotted(โฆ)
, which allow this as well.
Firefox already supports ::slotted(...)::before
and such so parsing them isn't webkit unique.
::slotted is different, as it selects elements. Same for ::part
Yeah, but the way they are currently specified and implemented violates the current <compoundโselector>
grammar.
Yup, this is a long-needed grammar change to reflect reality. The fact that the Scoping spec explicitly allowed ::slotted()::before
even tho it was grammatically invalid per Selectors just shows that we were behind the ball there. ^_^
Currently, theย grammar contains: [ <pseudo-element-selector> <pseudo-class-selector>* ]*
, where theย wrapping group has *
instead of ?
, which reads toย meย as:
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ โโโค โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ โโโข โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโฑโโฏ โฐโโฒโโโโโโโโโโโโโโโโโโโโโโโโโโฑโโฏ โ โ โฐโโจ <pseudo-element-selector> โ โโโโโโจ <pseudo-class-selector> โ โโโฬถโฐฬถโฬถโฎฬถโโฏ โญโบโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Which would indicate support for multiple pseudo elements.
...indeed it does. Cool.
I still think the syntax could be simplified.
NVM, thinking about it, the current system provides an easyโish way to get all the pseudoโclasses associated with a given pseudoโelement.
Most helpful comment
...indeed it does. Cool.