- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Tue, 24 Mar 2009 07:25:46 -0500
- To: Gabriele Romanato <gabriele.romanato@gmail.com>
- Cc: www-style@w3.org
2009/3/23 Gabriele Romanato <gabriele.romanato@gmail.com>: > For more specificity, we could write this pseudo-class as: > > E:parent(E1) > > Where E1 is the parent element: > > a:parent(h3) {...} CSS has had many proposals for a pseudoclass that goes 'in the opposite direction', and selects an element based on its children/descendants (or previous siblings). Unfortunately, in the general case it's a desperately expensive operation. Now that I've learned much more about selector engines and the way they operate (and *why* they operate that way), that sort of operation will pretty much *always* be extremely expensive. It can be reasonably implemented on a complete DOM tree, which is why javascript libraries like jQuery can do it, but it can't be done quickly on a DOM that is being built element-by-element as the HTML parser reads a file over the wire. Unfortunately this latter case is *by far* the most common cause of selector matching. In general, you need to be able to quickly grab all the selectors that can even *possibly* apply to a newly added or mutated element, and then walk up the tree to verify which ones actually do. Walking *down* the tree is enormously more expensive, as should be obvious (an element has a single parent, but possibly many children). That said, it appears, based on feedback from implementers, that implementing merely the parent selector, and perhaps the previous sibling selector, wouldn't be horrendous. It would still be slower than the existing simple selectors (even something that *seems* symmetric, like matching previous-sibling vs next-sibling, really isn't when you're consuming a document node by node). However, your syntax simply doesn't work. As you have it, you are targeting an <a> element, *not* the parent, and certainly not an <h3> element. The closest you could get is that you're targetting an <a> which has an <h3> as a parent, which is more simply written as "h3 > a". Pseudoclasses are just what they sound like - imaginary classes applied to elements based on some property they hold. You have to target the parent first, then select it based on its children. In the simple case, something like "h3:child(a)". In a more general form, "h3:matches( > a )". The latter has the advantage of being extensible when we find a good way to match more generally (or just get performant enough that we stop caring), but the former is much simpler for authors and doesn't have the 'unbalanced selector' that appears to cause problems for some. ~TJ
Received on Tuesday, 24 March 2009 12:26:23 UTC