Re: Proposal: parent selectors

On Wed, Jan 20, 2010 at 1:11 PM, Stephen Belanger <cyruzdraxs@gmail.com> wrote:
> This has probably been suggested before, but I didn't find it in a search.
> Currently we can find child elements like so;
> a > img
> This would return any image contained in a link--but what if you need to
> select any link containing an image? For that I propose an equivalent that
> runs in the opposite direction;
> img < a
> The css interpreter would start by finding all 'img' elements, then it would
> try to move one level up and, if an 'a' element is found, would return
> successful and add that element to the list of elements to apply that
> particular style to.

Yup, been discussed before.  ^_^  It's a difficult problem, though.

The general case is implemented in jQuery by the :has() pseudoclass.
You'd write "a:has(img)" to select an a that has an img descendant, or
"a:has(>img)" to be more specific about where the image is.

Unfortunately, while this is reasonable to implement once you have the
entire page built and ready like jQuery does, it breaks some very
important optimizations if you're trying to match selectors to
elements *while* the page is being built, which is the time when
browsers do the majority of their selector matching.  Basically, with
normal CSS you have all the information you need to find all the rules
that match an element as soon as the element appears; if you start
from the end of the selector and go backwards, you keep looking for
parents, ancestors, and previous siblings, all of which occur earlier
in the code and thus have already been parsed and inserted into the
page.  :has() breaks this, as it requires information about
descendants and later siblings, which means you can't match the rule
to an element until well after it's been parsed.

So, :has() is very inefficient.  It's also very useful, though, so
it's certain to show up in CSS at *some* point.

For now, though, Boris Zbarsky of Mozilla has indicated that a
:has-child() pseudoclass wouldn't be *too* inefficient, and so I
believe it's likely to show up in Selectors Level 4 (we've finished up
Level 3 already, and are pushing it through the standards track now).
I think :has-child() covers the majority of use-cases as well - my
main need for it is "label:has-child(:checked)", and your
"a:has-child(img)" would also work.

~TJ

Received on Thursday, 21 January 2010 14:27:18 UTC