The :lang
selector is very different from all other selectors (AFAIK).
Other selectors only (directly) effect the actual matched elements themselves, whereas the :lang
pseudo class is very different in that all elements within an element targeted by :lang selector are also directly targeted.
So let's say I place a border around an ul
element - only the ul
itself gets the border - not all of the list items (demo). Not so with :lang if I target that same ul which has an attribute of lang="en" - all of the list items will also get the border - to the extent that in order to override that rule (on the child !!) I have to use a selector with greater specficity (DEMO !!!).
:lang(en) {
border: 5px solid red;
}
<ul lang="en">
<li>item
<li>item
<li>item
<li>item
<li>item
</ul>
So I would like to know why the :lang selector was implemented in this very strange way. (apart from the fact that that's what it says in the spec) for the following reasons:
1) Counter-intuitive:
If we use the logic that all the descendants of the element with a lang attribute should be matched - because they share the same language - then conceptually the [lang] attribute selector should match in exactly the same way!
2) Not necessary:
a) Typically when dealing with different languages in a document you need to adjust text-related properties like font-family, font-size, color, quotes etc to suit the other language. The thing is that these properties anyway inherit such that by matching just the parent element element - all subsequent descendants get these changes. (demo)
b) If this functionality was necessary for some reason it could be achieved with the universal selector like so .parent,.parent * {}
(demo)