Description
The universal selector *
is not actually that universal, since it only selects elements, but not pseudo-elements.
This can be annoying. For example, some authors prefer the border-box sizing model and want to use it everywhere by default. Then they need something like
*, ::before, ::after { box-sizing: border-box }
Another example is ::marker
. Someone may want to assign some styles to all markers, but ::marker
alone only selects markers originated by elements, not by other pseudo-elements. So actually they will need
::marker, ::before::marker, ::after::marker { ... }
This may be easy to forget. Even the spec editors did! #4474
Also, currently ::marker is very restricted but in the future it may support arbitrary properties. So the 1st example may become
*, ::before, ::after, ::marker, ::before::marker, ::after::marker {
box-sizing: border-box;
}
To avoid this nonsense, I propose adding a new kind of universal selector that also selects tree-abiding pseudo-elements. I don't care about the syntax, but let's say e.g. **
.
Then, ** { box-sizing: border-box }
would switch everything to the border-box sizing model.
And **::marker
would select all markers.
Since this selector can select pseudo-elements, it should be restricted. It can only be used at the end of a complex selector, or immediately before a pseudo-element or a pseudo-class that is allowed after some tree-abiding pseudo-element. For example,
foo#bar > .baz **
is valid.**::marker
is valid because::before::marker
is valid, even if::marker::marker
is invalid.** ::marker
is invalid since there is a descendant combinator.**::before
is invalid since::before
can't appear after another pseudo-element. Alternatively, it could be a synonym of*::before
.**:hover
is valid because::before:hover
is valid**:root
is invalid since:root
can't appear after a pseudo-element. Alternatively, it could be a synonym of*:root
.
Also, until #2284 is resolved, **
shouldn't be allowed inside functions either. For example, :is(**)
is invalid.
I'm not that sure if **
should be allowed at the end of a compound selector after simple selectors, e.g.
#foo**
could be#foo, #foo::before, #foo::before::marker, ...
::slotted(.bar)**
could be::slotted(.bar), ::slotted(.bar)::before, ...