- From: Benjamin Poulain <benjamin@webkit.org>
- Date: Tue, 25 Nov 2014 13:37:39 -0800
- 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