:: first-letter与:first-child有什么不同(伪类与伪元素)

时间:2019-02-26 14:16:57

标签: css css-selectors standards w3c

根据W3C标准对伪元素https://www.w3.org/TR/selectors-3/#pseudo-elements的定义:

  

伪元素创建了除文档语言指定的抽象之外的有关文档树的抽象。例如,文档语言不提供访问元素内容的首字母或第一行的机制。伪元素允许作者引用本来无法访问的信息。

(我的重点。)

为什么文档语言完全允许检测第一个子元素(因此:first-child是css伪),但是为什么不允许第一个字母(因此::first-letter是CSS伪 element )?应该如何理解这种“ 文档语言”?

本质上,问题是:为什么选择第一个元素与选择第一个字母相比有什么区别?为什么文档语言只能检索一种语言?

我不是在问伪类和伪元素之间的一般区别,而是我要特别询问为什么第一个字母在概念上不同于第一个子元素。其他伪元素不太容易混淆:例如::after::before是伪元素就很明显,因为它们与html结构中未定义的“空格”有关。但是第一个字母,因此,为什么仍然要区别对待第一个字母的问题。

1 个答案:

答案 0 :(得分:3)

在最典型的CSS用例中,文档语言是指HTML。文档树(在整个选择器中都称为“树”)是指根据标记构造的DOM树。

伪元素是根据现有布局生成的东西。也就是说,必须首先根据应用于DOM树中元素的CSS构造和渲染布局。仅凭文档语言(即标记)无法做到这一点。

例如,您会注意到::first-letter伪元素仅适用于块状容器盒。在确定它是一个块容器框(唯一可以直接包含内联内容流的框)之前,无法知道一个元素(或其后代)是否具有::first-letter伪元素,这是由CSS而不是HTML决定的。作为更具体的示例:

<p>Hello world!

默认情况下,p元素是display: block。这将导致一个积木箱,这是一种积木容器箱。但是即使如此,此默认值还是使用CSS实现的。并且如果要使用以下CSS规则覆盖默认设置:

p {
  display: inline;
}

此元素随后成为一个内联框,p::first-letter将不再对其起作用。

直觉上,与内嵌框(或任何其他类型的框)相比,确定内嵌框的第一个字母似乎仍然微不足道,但是一旦在相同的内联格式上下文中有多个内嵌框,事情就变得相当复杂了。彼此互动。

::first-line更加清晰:不仅无法知道元素文本的第一行格式,直到您对它们进行 format 格式,而且内容和在调整元素大小和/或重排元素及其内容时,此行的长度也可以更改

相反,诸如:first-child之类的树结构伪类与布局的DOM 独立地匹配。无需渲染任何内容,浏览器可以立即判断出哪些元素是其父元素的第一个子元素。您只需要元素的DOM树,这意味着您可以从文档语言(即标记)中检索所需的所有信息。例如,以下片段中ol的第一个子元素总是相同,无论您对其应用哪种CSS

<ol>
  <li>First
  <li>Second
  <li>Third
</ol>