【问题标题】:What's the difference between html[lang="en"] and html:lang(en) in CSS?CSS 中的 html[lang="en"] 和 html:lang(en) 有什么区别?
【发布时间】:2019-03-21 00:03:25
【问题描述】:

CSS 语言伪类允许我们为不同的语言指定不同的样式,如下所示:

html:lang(en) .foo { ... }

但是,这在 IE7 中不起作用,所以我一直在使用属性选择器:

html[lang="en"] .foo { ... }

他们似乎做同样的事情,但有什么细微的差别吗?如果没有,当属性选择器做同样的事情时,为什么 CSS 甚至还有一个语言伪类?

【问题讨论】:

    标签: css css-selectors pseudo-class


    【解决方案1】:

    在 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 用于根据方向性匹配元素。因为方向性是与语言相关的属性,dirlang 属性在 HTML 中的工作方式类似,:dir() 与其对应的属性选择器之间的区别类似于:lang() 与其对应的属性选择器之间的区别——到以下引用的第一句实际上是描述:lang()的部分中同一段落的逐字复制

    :dir(C) 和 ''[dir=C]'' 之间的区别在于 ''[dir=C]'' 只对元素上的给定属性进行比较,而 :dir(C ) 伪类使用 UA 对文档语义的了解来执行比较。例如,在 HTML 中,元素的方向性继承,因此没有 dir 属性的子元素将具有与其最近的具有有效 dir 属性的祖先相同的方向性。作为另一个例子,在 HTML 中,匹配 ''[dir=auto]'' 的元素将匹配 :dir(ltr) 或 :dir(rtl) ,这取决于元素的解析方向性,由其​​内容确定。 [HTML5]

    【讨论】:

    • xml:lang 属性是否对 Web 浏览器不可见(因为 Web 浏览器是 HTML 解析器而不是 XML 解析器)?我一直在尝试通过用户 CSS 使用this w3 article 中列出的选择器,但它们不适用于this webpage。该日本网页上的&lt;html&gt; 元素仅指定xml:lang 属性,而不是lang 属性。
    • @3to5businessdays:是的,尽管我应该指出,现代浏览器实际上同时具有 HTML 和 XML 解析器 - 使用哪个解析器取决于服务器给出的内容类型。无论如何,如果&lt;html&gt; 元素只包含xml:lang 属性而不包含lang 属性,那么它是无效的。这是因为,在 HTML 中,只有 lang 属性适用,这就是 :lang() 伪不匹配的原因。
    • 我不小心投了反对票,请您做一个小改动,以便我删除投票吗?
    • @Florian:完成。
    【解决方案2】:

    其他人没有提到的另一件事 - :lang() 伪类对如何设置元素的语言不感兴趣。在 XHTML 文档(具有 XML MIME 类型的真正 XHTML)中,您可以使用 xml:lang="en" 并且该元素将匹配 :lang(en) 但不匹配 [lang="en"]

    【讨论】:

    • 或者更确切地说,规范提到了它。
    【解决方案3】:

    According to the spec,

    如果文档语言指定了如何确定元素的人类语言,则可以在 CSS 中编写选择器,以根据元素的语言匹配元素。例如,在 HTML [HTML4] 中,语言由“lang”属性、META 元素以及可能来自协议的信息(例如 HTTP 标头)的组合确定。 XML 使用一个名为 xml:lang 的属性,并且可能还有其他特定于文档语言的方法来确定语言。

    如果元素使用 C 语言,则伪类 ':lang(C)' 匹配。是否匹配仅基于标识符 C 是否等于或由连字符分隔的元素的子字符串语言值,就像由 '|=' 运算符执行的一样。对于 ASCII 范围内的字符,C 与元素的语言值的匹配不区分大小写。标识符 C 不必是有效的语言名称。

    即:

    1. 除了简单的lang 属性外,它还适用于许多其他指定语言的方法。
      • 最重要的是,正如@BoltClock 的回答中所详述的那样,它将使用容器元素上指定的语言(以任何方式),而不仅仅是元素本身,因为语言是由子元素继承的。
    2. 它使用|= 语义,即:lang(en):lang(us) 都将匹配span[lang=en-us]
    3. 保证不区分大小写,而

    选择器中的属性名称和值是否区分大小写取决于文档语言。

    【讨论】:

      【解决方案4】:

      Css 支持所有元素的属性选择器,而不仅仅是html 标签lang 属性。例如像&lt;a title="Jeeha" href="foo.html"&gt;bar&lt;/a&gt;这样的html可以像a[title=Jeeha] { ... }那样在css中选择。

      有关部分匹配和变体的更多详细信息,请参阅this 链接。

      【讨论】:

        猜你喜欢
        • 2021-08-25
        • 1970-01-01
        • 2023-03-27
        • 2019-11-07
        • 1970-01-01
        • 1970-01-01
        • 2020-07-02
        • 1970-01-01
        • 2011-06-05
        相关资源
        最近更新 更多