- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Wed, 14 Jan 2009 13:00:51 -0600
- To: "Giovanni Campagna" <scampa.giovanni@gmail.com>
- Cc: www-style@w3.org
On Wed, Jan 14, 2009 at 10:55 AM, Giovanni Campagna <scampa.giovanni@gmail.com> wrote: > Well, "a > b < c d < e" means an element "e" that is parent of "d", > descendant of "c", parent of "b", child of "a" > because b should be child of "a" and "c" at the same time, this doesn't > match anything, but it is not difficult to read, if you read starting from > the last token (as you do with current selectors) As noted in an earlier email, I intended the letters to be generic placeholders for simple selectors, but I also could have been more clear by using "a" twice, rather than "c". Assuming I wrote it like that, the selector as given is still useful. As I responded to Boris, it is equivalent to the selector (written with my proposed syntax) "a:matches(> b) e:matches(> d)". > ... > Furthermore, I'm not personally against a :matches pseudoclass (in addition > of # placeholder) just I expected it to be "element matches selector > contained in pseudoclass", not just element is "parent or sibling", and this > can be very expensive at computation time (at least linear on number of > element matching the selector without pseudoclass), while instead <, <<, - > and -- can be optimized Yes, from what implementors have told me (and it makes complete sense, given my current limited knowledge of CSS engines and browser parsing) a general matching pseudoclass that accepts any selector would be *very* expensive. I explicitly limited my proposal to only matching children and adjacent siblings due to feedback from Boris in an earlier discussion, where he said that matching only against those would likely be reasonable enough to be implementable. Optimizing a "<<" combinator is equivalent to optimizing "a:matches(b)" (that is, a descendant matcher, rather than just a child matcher). According to feedback from Boris, it's probably not doable. > Frex, I expect that in selector "myancestor #my-id", first UA gets #my-id > (only one element, found from ID map), then finds a myancestor some where in > the tree, without travelling all the DOM: this means that fast ways to get > from child to parent - ancestor. For siblings, the concept is similar: UAs > already optimized +, I don't think it is much of runtime expense to use the > same patterns but to select a different element. I thought the same thing, but have learned that this is not the case. There's a *reason* we have a + combinator and not a - one. CSS engines are optimized to work on the html stream *as it is parsed* element-by-element. They can do this relatively cheaply if they can be guaranteed that determining if an element matches a rule is dependent *only* on information that has already been parsed. The four current combinators respect this restriction, but <, <<, -, and -- (or their :matches() equivalents) do not, which is why it's such a concern, and why I restricted my own proposal so severely. I made sure it sat within lines that an implementor said would likely be acceptable. To put it another way, CSS engines do not determine matches against a complete document. They do so against an incomplete document as it is streamed, and so several situations that *appear* symmetrical and easy really are not. This is why javascript libraries like jQuery *can* implement complex selectors like this relatively simply and with decent performance - by the time their matching routines run, the entire DOM is loaded, and so they *can* exploit those symmetries. ~TJ
Received on Wednesday, 14 January 2009 19:01:27 UTC