Re: Selector for tags with a certain child.

On Thu, Oct 9, 2008 at 9:48 AM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
> The discussion spawned off of that thread [1] between me and Boris, though,
> came to the conclusion that a simple parent selector wouldn't be overly
> burdensome (a previous-adjacent-sibling selector would be worse, a
> previous-sibling selector worse still, and an ancestor selector worst of
> all).  It can cause reflowing, but the damage is relatively limited (to only
> the parent and any siblings+children), and the computational hit of
> computing matches is minor in this simple case.
>
> [1]:http://lists.w3.org/Archives/Public/www-style/2008Jul/0603.html

His answer was kind of noncommittal, I think:

> For "foo:matches(> bar)", if that means "a <foo> which has a <bar>
> child" that means that in genera we need to reresolve the parent of a
> node being inserted or removed (plus of course all its descendants).
> This can be optimized a bit by keeping track of whether such a :matches
> is around and would have to be, because adding children to an
> <html:body> is pretty common during parsing.
http://lists.w3.org/Archives/Public/www-style/2008Jul/0625.html

The basic point is that for DOM appends, you have to re-render one or
more elements for all these selectors, or else delay progressive
rendering.  The parent selector could be unpleasant if you were doing
something like "body:child(div.myclass)" and that got hit late in a
long document, whatever you do.  Until everyone has a lot more
CPU/network bandwidth and everything parses instantly, maybe.  :)
(But "adjacent sibling" is automatically limited to having to
reflow/delay for only one element, so it's probably more feasible:
"pretty easy" and "doesn't sound too bad", as Boris said.)

I think a couple of more limited variants could be implemented
cheaply, though.  For instance, "an X whose *first* child is a Y"
should be no problem at all: just don't begin rendering the element
until you've got the opening tag of its first child, which should be
just about immediately.  This might work in a considerable percentage
of use-cases for a general parent selector.  You might even be able to
do "an X whose 'first descendant' is a Y", so a hypothetical
"div:first-descendant(input)" would match the outermost div of

<div><fieldset><input ...></fieldset></div>

again, I hope -- not being too savvy on the implementation of such
things -- without much cost.  The point would be to not allow any text
or other stuff that actually needs to be rendered in between the tag
you're actually matching and the opening tag you're checking for.  You
wouldn't have to reflow anything, and I'm guessing you wouldn't
significantly delay progressive rendering.

I guess you might have to wait a bit longer to start drawing borders
and so on, things that only depend on the outer element -- you'd have
to wait for the opening tag(s) of the next element(s) to be parsed.
But a) it should be a very short wait in any remotely reasonable case
(yeah, str_repeat( '<div>', 50000 ) would be slow, granted), and b) I
don't know how common such things are anyway -- in many cases you'd
have to wait for at least the beginning of the element's contents to
be able to start drawing any of it anyway (e.g., you can't draw the
background of a typical empty div, since it will be zero-height until
it has contents).

What were the use cases given for a parent selector again?  The one
that springs to mind is things like styling wrappers differently if
they contain form controls, as in my example above, which this weaker
(and faster?) variant might well allow in many cases.

Received on Friday, 10 October 2008 15:09:16 UTC