3
votes

Given a CSS selector like

ul > li a

Would it be easier/faster to evaluate it from left to right, or right to left? (I realize the answers for "easy" and "faster" might be different.. I want the answer to both). I'm about to embark down one of these paths and I don't want to get half way there and then realize I chose the wrong path :)

LTR: Iterate over all the elements in the document, pick out the ones that are ul, then check all their children for li, and then look at their descendants for a.

RTL: Iterate over all the elements in the document, find all the a, filter out the ones that don't have an ancestor that is an li, if it does have an li ancestor, check if its parent is a ul, if not, drop that a.

Also, there isn't really any other way to do this than iterating over all the elements is there?


I'm thinking in the context of finding elements, as jQuery does, not in the context of applying styles.

2
It's just a plain ol' CSS2 selector. Nothing 3 about it. Just saying :PBoltClock
@BoltClock: Woops... good point. I plan on supporting CSS3, but I guess thats not relevant to this specific question.mpen

2 Answers

4
votes

Browsers, and the Sizzle selector JS engine (what is used in jQuery and other frameworks) use right to left matching.

Right to left works out to be the most optimal traversing solution in most situations.

Sizzle optimizes selectors that start with an ID. It resolves the element with the ID first. It then uses that as context for further traversing.

So if you have the selector

#myID > ul a

Sizzle will find the element with #myID first, assuming that in this case, left to right is more optimal.

2
votes

This is one of those questions repeated on every design and programming forum. A common example is also the one given by the original poster on this thread:

ul > li a

if you traverse ltr you find all uls and then all lis of those uls and then all a tags in those lis. Consider the fact that the markup may look like:

<ul>
    <li>
        <a href="#">Click Here</a>
    </li>
</ul>

or it may look like:

<ul>
    <li>
        <span>
            <p>
                <div class="someuselessclass">
                    <span class="JunkClass">
                        <a href="#">Click Here</a>
                    </span>
                </div>
            </p>
        </span>
    </li>
</ul>

The fact is, you don't know how deep the traversal will have to go and there may be thousands of such links in thousands of such LIs. Seems to me that through experience, the browser builders that be have come to the conclusion that it is faster to parse Right To Left.

That's my two cents.