在 HTML 中,:lang() 伪类和属性选择器都将匹配具有相应 lang 属性的元素。
不同之处在于,当针对:lang() 伪类进行测试时,浏览器可能有其他方法来确定给定元素的语言,该伪类可能由文档语言和/或实现定义,而属性选择器将仅检查元素的给定属性,不附带任何基于文档的语义。
例如,在 HTML 中,伪类还将匹配没有不同 lang 的元素的任何后代,具体取决于浏览器如何确定这些后代的语言。通常,如果没有明确设置,后代将继承其祖先的语言属性。
spec 是这样说的:
:lang(C) 和 '|=' 运算符之间的区别在于,'|=' 运算符只对元素上的给定属性执行比较,而 :lang(C) 伪类使用 UAs 的知识文档的语义来执行比较。
在这个 HTML 示例中,只有 BODY 匹配 [lang|=fr](因为它具有 LANG 属性),但 BODY 和 P 都匹配 :lang(fr)(因为两者都是法语)。 P 与 [lang|=fr] 不匹配,因为它没有 LANG 属性。
<body lang=fr>
<p>Je suis français.</p>
</body>
请注意“具有 LANG 属性”和“在法语中”的具体措辞。正如您所想象的那样,这两个短语在英语中的含义非常不同。
在您的示例中,以下选择器也将匹配您的 .foo 元素:
.foo:lang(en)
但以下选择器不会,如果它没有自己的lang 属性集:
.foo[lang="en"]
.foo[lang|="en"]
至于浏览器支持,从 IE8 开始支持 :lang() 伪类,因此 IE7 确实是唯一一个通过在属性选择器上使用伪类将无法支持的浏览器。
基于这种理解,您可以回答“我应该使用哪个”的问题:默认情况下您应该始终使用 :lang() 伪类,除非某些怪癖(或需要支持IE7) 需要使用属性选择器来解决。
选择器 4 不仅有 brings enhanced functionality to the :lang() pseudo-class(从而扩大了它和属性选择器之间的功能差距),而且还有 introduces the :dir() pseudo-class 用于根据方向性匹配元素。因为方向性是与语言相关的属性,dir 和 lang 属性在 HTML 中的工作方式类似,:dir() 与其对应的属性选择器之间的区别类似于:lang() 与其对应的属性选择器之间的区别——到以下引用的第一句实际上是描述:lang()的部分中同一段落的逐字复制:
:dir(C) 和 ''[dir=C]'' 之间的区别在于 ''[dir=C]'' 只对元素上的给定属性进行比较,而 :dir(C ) 伪类使用 UA 对文档语义的了解来执行比较。例如,在 HTML 中,元素的方向性继承,因此没有 dir 属性的子元素将具有与其最近的具有有效 dir 属性的祖先相同的方向性。作为另一个例子,在 HTML 中,匹配 ''[dir=auto]'' 的元素将匹配 :dir(ltr) 或 :dir(rtl) ,这取决于元素的解析方向性,由其内容确定。 [HTML5]