The CSS language pseudo-class to allow us specify different styles for different languages, like so:
html:lang(en) .foo { ... }
However, th
Css supports attribtue selectors for all elements, not just for the html
tags lang
attribute. For example html like <a title="Jeeha" href="foo.html">bar</a>
could be selected like a[title=Jeeha] { ... }
in css.
See this link for more details on partial matches and variants.
One more thing that wasn't mentioned by anybody else - :lang()
pseudoclass isn't interested in how one sets the element's language. In XHTML document (true XHTML with XML MIME type), you can use xml:lang="en"
and the element will match :lang(en)
but not [lang="en"]
.
In HTML, both the :lang()
pseudo-class and the attribute selector will match an element with the corresponding lang
attribute.
The difference is that a browser may have other ways of determining the language of a given element when testing against the :lang()
pseudo-class which may be defined by the document language and/or the implementation, whereas an attribute selector will only check an element for that given attribute, without any accompanying document-based semantics.
For example, in HTML, the pseudo-class will also match any of the element's descendants for which there isn't a different lang
, depending on how a browser determines the language for those descendants. Usually, the descendants will inherit the language attribute from their ancestor if it is not explicitly set.
Here's what the spec says:
The difference between
:lang(C)
and the ‘|=’ operator is that the ‘|=’ operator only performs a comparison against a given attribute on the element, while the:lang(C)
pseudo-class uses the UAs knowledge of the document's semantics to perform the comparison.In this HTML example, only the BODY matches
[lang|=fr]
(because it has a LANG attribute) but both the BODY and the P match:lang(fr)
(because both are in French). The P does not match the[lang|=fr]
because it does not have a LANG attribute.<body lang=fr> <p>Je suis français.</p> </body>
Notice the specific phrasings of "has a LANG attribute" and "are in French". These two phrases have very different meanings in English, as you might imagine.
In your example, the following selector will also match your .foo
element:
.foo:lang(en)
But the following selectors won't, if it doesn't have its own lang
attribute set:
.foo[lang="en"]
.foo[lang|="en"]
As for browser support, the :lang()
pseudo-class is supported starting from IE8, so IE7 really is the only browser you will be unable to support by using the pseudo-class over the attribute selector.
Based on this understanding you can then answer the question "which should I use": you should always use the :lang()
pseudo-class by default, unless certain quirks (or the need to support IE7) require working around by using an attribute selector instead.
Selectors 4 not only brings enhanced functionality to the :lang() pseudo-class (thereby widening the gap in functionality between it and attribute selectors), but also introduces the :dir() pseudo-class for matching elements based on their directionality. Because directionality is a language-related property, the dir
and lang
attributes work similarly in HTML, and the difference between :dir()
and its corresponding attribute selector is analogous to that between :lang()
and its corresponding attribute selector — to the point where the first sentence of the following quotation is in fact a word-for-word copy of the same paragraph in the section describing :lang()
:
The difference between :dir(C) and ''[dir=C]'' is that ''[dir=C]'' only performs a comparison against a given attribute on the element, while the :dir(C) pseudo-class uses the UAs knowledge of the document’s semantics to perform the comparison. For example, in HTML, the directionality of an element inherits so that a child without a dir attribute will have the same directionality as its closest ancestor with a valid dir attribute. As another example, in HTML, an element that matches ''[dir=auto]'' will match either :dir(ltr) or :dir(rtl) depending on the resolved directionality of the elements as determined by its contents. [HTML5]
According to the spec,
If the document language specifies how the human language of an element is determined, it is possible to write selectors in CSS that match an element based on its language. For example, in HTML [HTML4], the language is determined by a combination of the "lang" attribute, the META element, and possibly by information from the protocol (such as HTTP headers). XML uses an attribute called xml:lang, and there may be other document language-specific methods for determining the language.
The pseudo-class ':lang(C)' matches if the element is in language C. Whether there is a match is based solely on the identifier C being either equal to, or a hyphen-separated substring of, the element's language value, in the same way as if performed by the '|=' operator. The matching of C against the element's language value is performed case-insensitively for characters within the ASCII range. The identifier C does not have to be a valid language name.
That is:
lang
attribute.
|=
semantics, i.e. :lang(en)
and :lang(us)
will both match span[lang=en-us]
.The case-sensitivity of attribute names and values in selectors depends on the document language.