[selectors5] Proposal for a pseudo combinator

Right now, pseudo-elements are selected by appending a "::foo" to the
end of a compound selector, as if it were any other simple selector.
This syntax dates back from CSS1, when the only pseudo-elements were
:first-line and :first-letter, which are heavily restricted in what
properties they can take.  In many ways, these can be considered to
not be elements at all, but rather simply a special way to apply
properties to a subset of text.

This changed with CSS2 and its introduction of ::before and ::after -
these were completely unrestricted in the properties they could
accept, and are generally identical to 'real' elements.  However, for
consistency we stuck with the CSS1 syntax for pseudo-elements, only
changing from a single colon to a double colon.

This syntax has some drawbacks.  For one, it's unclear from the syntax
that what you're actually selecting is a brand new element - this is
usually indicated by the use of a combinator, but :: doesn't have the
qualities of a combinator.

For two, the syntax forces the pseudo-element to be at the end of the
selector, which prevents us from filtering based on qualities of the
pseudo-element, such as wanting to style it differently when hovered.
(This is another legacy from CSS1, where there were no pseudo-classes
that could possibly apply to pseudo-elements.)

For three, this prevents us from implying more structure inside of the
pseudo-element.  For example, if a ::before is set to "display:
list-item;", it will generate a list marker, but the syntax prevents
us from actually *selecting* the ::marker pseudo that's inside of it.
In the Web Components effort, one potential method for selecting into
the shadow tree is using a ::shadow pseudo-element that matches the
root of the shadow tree attached to an element, but the current syntax
prevents us from digging further into the shadow DOM from there.

For all of these reasons, I propose that in Selectors 5 we reify
pseudo-elements properly, making them real elements (from the
perspective of Selectors) that are targeted with a "pseudo"
combinator.  I propose this combinator be the double-colon we
currently use to indicate pseudo-elements.

This would allow selectors like "p :: before:hover", yay!  If we in
the future relax the restriction of "one pseudo-element per selector",
a selector like "p :: before :: before" seems easier to read than
"p::before::before".

One further change is needed to give this proposal complete
backwards-compatibility - allow sequences of multiple combinators,
which imply a universal selector between them.  Then, selectors like
"p > ::before" would still be valid *and* would match the exact same
elements as today - it would be identical to the selector "p > * ::
before".

~TJ

Received on Thursday, 5 April 2012 22:45:33 UTC