CSS 伪类和伪元素的区别

伪类(pseudo class)和伪元素(pseudo element)这两个概念一直被混淆。

简而言之:

  • 伪类,会对现有的元素进行筛选。
  • 伪元素,会创造出不存在的新元素。

我们来看看标准是怎么说的:

  • 伪类

The pseudo-class concept is introduced to permit selection based on information that lies outside of the document tree or that cannot be expressed using the other simple selectors.

  • 伪元素

Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element’s content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document.

「伪类」的作用为「permit selection」,即允许选择一些无法用其他选择器选取的元素,必须对应某个现有的 HTML 元素。而「伪元素」则「create abstractions about the document tree beyond those specified by the document language」,意思是它并不依赖于 HTML 树的结构,即可以创造新的元素。

例如,:first-child是一个伪类,对应作为第一个子元素的元素;:visited作为一个伪类,对应所有已经被访问过的a元素。

::before作为一个伪元素,对应某元素之前一个(实际不存在的)元素。同时::selection作为一个伪元素,它并不代表被选择的元素,而代表被选择的内容(可能是一个元素的一部分)。其他伪元素的例子还有::first-line,对应第一行,等等。

表示方法

简而言之:伪类总是以一个冒号开头。伪元素通常以两个冒号开头。

在 CSS2 时代,伪元素和伪类均是以一个冒号开头的;在 CSS2.1 之后,为了对伪元素和伪类加以区分,规定伪类继续以一个冒号开头,而伪元素改为以两个冒号开头。但是为了向前兼容,浏览器同样接受 CSS2 时代已经存在的伪元素(它们包括:before, :after, :first-line, :first-letter)的单冒号写法。但是对于 CSS2 之后所有新增的伪元素(例如::selection),必须采用双冒号写法。

浏览器兼容性

一些老旧的浏览器不支持双冒号的写法,因此如果必须兼容旧浏览器,则应该使用单冒号写法。IE 从 9 开始支持双冒号写法。

本文作者为,最后修订于

讨论