CSS 伪类和伪元素的区别

伪类(pseudo class)

  • 伪类是一个抽象类,本质上还是一个类,因此其主要作用仍然是用来选择元素而后设定具体的样式。
  • 伪类,会对现有的元素进行筛选。
  • 伪类总是以一个冒号开头。
  • 伪类选择元素的依据不是名称、属性或内容,而是根据特征(比如状态或顺序)。(:lang除外)
  • 伪类的选择对象可能会随着用户操作文档而发生变化,比如当用户删除某些节点后,会影响子元素(nth-child)伪类的选择。

伪元素(pseudo element)

  • 伪元素本质上是一个元素,只是它一般需要依附在一个已有元素上,作为这个元素的“部分”或“补充”。比如::first-line或::after。
  • 伪元素,会创造出不存在的新元素。
  • 伪元素通常以两个冒号开头。
1
2
3
4
5
「伪类」的作用为「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,对应第一行,等等。

浏览器兼容性

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