Re: a recall for a missing combinator

On Tue, Nov 15, 2011 at 2:06 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:
> On 11/16/11 4:49 AM, Tab Atkins Jr. wrote:
>>
>> I approve of this.  Let's call it the "closest descendant" combinator.
>>  Perhaps it could look like ">>".
>
> What would it match, exactly?  Recall that the requirement is to have
> something that given this markup:
>
>  <article class=”product>
>                <header>…</header>
>                <div class=”main”>
>                               <article class=”review”>
>                                               <header>…</header>
>                                               …
>                               </article>
>                </div>
>  </ article>
>
> matches only the first <header>.
>
> Seems to me like that's already possible with the proposed changes to :not,
> by the way:
>
>  article.product header:not(article.review header)
>
>> It's like the descendant
>> combinator, except when you're walking up the tree to find the
>> ancestor, you *also* look for someone else that matches the
>> descendant.
>
> If you just did that then you would match both <header>s in the testcase
> above.  So that doesn't work to address the use case put forward.

Ah, duh, I should have thought about this more.  Yeah, this doesn't
quite solve the problem.  It looks like for the problem in question we
*will* need either complex-selectors-in-:not() or some other way of
blocking the selector from propagating too far down.

Generically, if we assume that there are consistent building-block on
the page that we don't want to target through, we'd have to write our
selector something like:

article.product header:not(article.product article header)

(This assumes that articles are our building block that we want to scope to.)

This seems pretty verbose, though.  We might be able to do better with
a more tailored expression, which I've had some ideas about:

@scope article.product {
  @stop article;
  header { ... }
}

This pulls in the scoping mechanism that <style scoped> uses and gives
it CSS syntax, and adds the ability to declare a "stop" selector.
Selectors within the scope block are prevented from matching the stop
elements or their subtrees.  All selectors within the scope, including
stop selectors, are resolved relative to the outer scope.

In other words, the generic form:

@scope <scope-selector> {
  @stop <stop-selector> {
  <nested-selector> { ... }
}

desugars to:

<scope-selector> <nested-selector>:not(<scope-selector>
<stop-selector> <nested-selector>)

similar to what you and I said above.

~TJ

Received on Tuesday, 15 November 2011 23:22:15 UTC