W3C home > Mailing lists > Public > www-style@w3.org > November 2014

Re: [selectors] Assistance requested in figuring out the data model of pseudo-elements

From: Benjamin Poulain <benjamin@webkit.org>
Date: Tue, 25 Nov 2014 13:37:39 -0800
Message-ID: <5474F6A3.3040002@webkit.org>
To: "Tab Atkins Jr." <jackalmage@gmail.com>, www-style list <www-style@w3.org>
On 11/24/14, 4:29 PM, Tab Atkins Jr. wrote:
> I'm trying to come up with the right text to express that
> pseudo-elements can be used in :matches(), per the thread at
> <http://lists.w3.org/Archives/Public/www-style/2014Aug/0402.html>, and
> I'm having a hell of a time.
>
> The basic problem is that our syntactic model for pseudo-elements is a
> giant mess.  Ignoring pseudo-elements, selectors are composed of
> simple selectors, which filter the current match set, and combinators,
> which transform the current match set.  But pseudo-elements lie
> in-between those two - they're syntactically similar to a simple
> selector, but they act like a combinator, transforming the match set
> into a different set of nodes.
>
> Because of this confused identity, pseudo-elements don't work well
> with our abstractions.  If you want both the <a> and <b> children of
> an element, you can write `foo > *:matches(a,b)`.  But if you want the
> ::before and ::after pseudo-elements of an element, there's no real
> equivalent - it's impossible to first transform the match set into one
> that contains the pseudo-elements in question, and then write a
> :matches() argument that'll match them.
>
> Instead, I'm going to have to allow something like
> `foo:matches(::before, ::after)`, which is broken, semantically - the
> :matches() pseudo is *supposed* to just be another filter for the
> compound selector, but this instead makes it *change* the node the
> compound selector is pointing to.  This makes things even more
> complicated, too, because suddenly the order of the simple selectors
> in the compound selector matter - just like `foo::before:hover` is
> different from `foo:hover::before`, `foo:matches(::before):hover` is
> different than the other order.  (Again, this is because
> pseudo-elements are actually combinators+selector pairs, not simple
> selectors. ARGH.)
>
> Does anyone know any way to express this sanely, or am I just going to
> have to grin and bear it and deal with the inconsistency that
> pseudo-elements are allowed in places that combinators aren't?
My 2 cents, not sure if that helps:

My own mental model for pseudo element is not one of a combinator that 
goes into some kind hidden element.

The way I use pseudo-elements is as a "generator", to create fake 
styling elements where there is none. For example, if I use:
     :matches(::first-line, ::before) { ... }
I think of it as if the engine generates elements for the first-line and 
something before the current element.

In my mind, the way it works with :matches() is as if the rules were 
expanded and the pseudo-elements were moved to the end.
For example:
     :matches(a, b):matches(*, ::before, ::after)
     ->*:matches(a, b), :matches(a, b)::before, :matches(a, b)::after
     ->a, b, a::before, b::before, a::after, b::after.

Conflicts simply don't "generate" anything that can match, say:
     :matches(*, ::before)::matches(::after)
     ->*::after, ::before::after (does not generate anything)
etc.

In practice in WebKit, we have been using :matches() as a magic operator 
that generates a disjunctive normal form of the selector.

Benjamin
Received on Tuesday, 25 November 2014 22:06:56 UTC

This archive was generated by hypermail 2.3.1 : Monday, 2 May 2016 14:39:26 UTC