Is It Easier/Faster to Evaluate CSS Selectors Ltr or Rtl

Is it easier/faster to evaluate CSS selectors LTR or RTL?

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.

Why do browsers match CSS selectors from right to left?

Keep in mind that when a browser is doing selector matching it has one element (the one it's trying to determine style for) and all your rules and their selectors and it needs to find which rules match the element. This is different from the usual jQuery thing, say, where you only have one selector and you need to find all the elements that match that selector.

If you only had one selector and only one element to compare against that selector, then left-to-right makes more sense in some cases. But that's decidedly not the browser's situation. The browser is trying to render Gmail or whatever and has the one <span> it's trying to style and the 10,000+ rules Gmail puts in its stylesheet (I'm not making that number up).

In particular, in the situation the browser is looking at most of the selectors it's considering don't match the element in question. So the problem becomes one of deciding that a selector doesn't match as fast as possible; if that requires a bit of extra work in the cases that do match you still win due to all the work you save in the cases that don't match.

If you start by just matching the rightmost part of the selector against your element, then chances are it won't match and you're done. If it does match, you have to do more work, but only proportional to your tree depth, which is not that big in most cases.

On the other hand, if you start by matching the leftmost part of the selector... what do you match it against? You have to start walking the DOM, looking for nodes that might match it. Just discovering that there's nothing matching that leftmost part might take a while.

So browsers match from the right; it gives an obvious starting point and lets you get rid of most of the candidate selectors very quickly. You can see some data at http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665 (though the notation is confusing), but the upshot is that for Gmail in particular two years ago, for 70% of the (rule, element) pairs you could decide that the rule does not match after just examining the tag/class/id parts of the rightmost selector for the rule. The corresponding number for Mozilla's pageload performance test suite was 72%. So it's really worth trying to get rid of those 2/3 of all rules as fast as you can and then only worry about matching the remaining 1/3.

Note also that there are other optimizations browsers already do to avoid even trying to match rules that definitely won't match. For example, if the rightmost selector has an id and that id doesn't match the element's id, then there will be no attempt to match that selector against that element at all in Gecko: the set of "selectors with IDs" that are attempted comes from a hashtable lookup on the element's ID. So this is 70% of the rules which have a pretty good chance of matching that still don't match after considering just the tag/class/id of the rightmost selector.

how to base a css rule on inherited value of dir attribute

There is now a proposed solution for this in the CSS spec: Logical Properties. Basically instead of applying different property values based on some other element's dir attribute, browsers are going to start having property values that are directionally aware.

So in a perfect world, once these have full support you could write:

.float-end {
float: inline-end;
}

These new values will exist for lots of properties, not just float. Support as of July 2019 is pretty much everybody but Microsoft (IE/Edge), go figure.

What is the difference between E:dir(dir) and E[dir=dir] in CSS?

According to MDN, some subtle differences exist:

The :dir CSS pseudo-class matches elements based on the directionality
of the text contained in it. In HTML, the direction is determined by
the dir attribute. For other document types there may be other
document methods for determining the language.

Note that the usage of the pseudo-class :dir() is not equivalent of
using the [dir=…] attribute selectors. The latter matches a value of
the dir and doesn't match when no attribute is set, even if in that
case the element inherits the value of its parent; similarly [dir=rtl]
or [dir=ltr] won't match the auto value that can be used on the dir
attribute. In the opposite, :dir() will match the value calculated by
the UA, being inherited or the auto value.

Also :dir() considers only the semantic value of the directionality,
the one defined in the document, most of the time in HTML. It won't
consider styling directionality, the one set by CSS properties like
direction which are purely stylistic.

css: dir=rtl VS style=direction:rtl

As you can't modify the HTML, a really really hacky selector would be:

div[style*="direction:rtl"] {
...
}

JSFiddle demo.

Note that I'm using style*= as opposed to just style= as this will also match elements which have more than just direction:rtl declared within the element's style property.

For extra strength in the selector, you could also use [style*="direction: rtl"] to handle style attributes which separate the values from the properties with a space:

[style*="direction:rtl"], [style*="direction: rtl"] { ... }

Alternatively in this case you could just match on a style attribute which contains "rtl", as I'm pretty sure this combination of characters isn't used in any other property (ignoring external resources like background image file names):

[style*="rtl"] { ... }

Updated JSFiddle demo.

HTML select and option mixed directions (ltr & rtl)

direction: rtl; is not exactly text alignment. Or to be precise text alignment is a side effect of direction. Note that direction also affects position of the dropdown arrow in your setup.

Conventional browsers do not allow you to style select element (it looks significantly different on different platforms, especially mobiles).

In Sciter you can style <select> parts individually as select components are normal DOM elements there:

select > caption { text-align:right; } 
select > button { ... }
select > popup > option { text-align:left; }

I've made it possible as Sciter is designed specifically for desktop UI and <select> styling is a must there.

As a solution for plain web pages I would suggest to use <select> substitutes like http://getbootstrap.com/components/#btn-dropdowns

How is the jQuery selector $('#foo a') evaluated?

That is correct - Sizzle (jQuery's selector engine) behaves the same way as CSS selectors. CSS and Sizzle selectors are evaluated right-to-left, and so #foo a will find all a nodes, then filter those by nodes that descend from #foo.

You improve this by ensuring that your leaf selectors have a high specificity, usually by giving them a class or ID.



Related Topics



Leave a reply



Submit