css2.1 Selectors章节中对伪类与伪元素的描述: CSS introduces the concepts of pseudo-elements and pseudo-classes to permit formatting based on information that lies outside the document tree.
也就是说,伪类和伪元素是用来修饰不在文档树中的部分,比如,一句话中的第一个字母,或者是列表中的第一个元素。
一、基本概念
伪类
用于当已有元素处于的某个状态时,为其添加对应的样式;
效果等同于给元素添加一个类,然后定义这个类的样式。(由于它只有处于dom树无法描述的状态下才能为元素添加样式,所以将其称为伪类。)
常见伪类:
-
:link
,:visited
,:hover
,:active
,:focus
(状态) -
:first-child
,:first-of-type
,:last-child
,:last-of-type
,:not
,:nth-child
,:nth-last-child
,:nth-of-type
,:only-child
,:only-of-type
(结构) -
:checked
,:default
,:disabled
,:invalid
,:read-only
, etc.(表单验证相关) -
:lang
,:dir
(语言相关)
伪元素
用于创建一些不在文档树中的元素,并为其添加样式。
效果等同于创建一个虚拟的(不存在于DOM树的)元素,并为之添加样式。
常用伪元素:
-
::first-letter
(相当于创建了一个<span>
来包裹首字母) ::first-line
::before
::after
二、用法与讨论
1. 伪元素用单冒号还是双冒号?
CSS3中伪元素用双冒号::
,如 ::after
,以区分伪类的单冒号 :
,如 :hover
;
但出于兼容性考虑,目前规范建议都使用单冒号。
2. 伪类选择器加与不加空格的区别?
(这里讨论的主要是结构性伪类选择器,且待考证,欢迎讨论)
- 伪类选择器前不加空格:选择的是元素本身;
- 伪类选择器前加空格:选择的是元素的子元素(且不一定是该种元素);
实例:
<div>
<span>A</span>
<span>B</span>
<span>C <em>D1</em><em>D2</em><a>E1</a><a>E2</a></span>
<span>F <span>G</span></span>
<span>H</span>
</div>
若不加空格(如下例),修饰的是<span>
元素,且该元素是其父元素下的第一个<span>
元素,因此 A 和 G 呈红色:
span:first-of-type {
color: red;
}
若加空格(如下例),修饰的是<span>
元素的子元素中,第一个任意类型的元素;可能选中多个,且选中的元素不一定是<span>
元素,因此 D1,E1 和 G 呈黄色:
span :first-of-type {
color: yellow;
}
经验证 :first-child
, :first-of-type
, :nth-child
符合以上用法,且:first-of-type
的 MDN文档内也列举了这两种用法。
3. :first-child
和 :first-of-type
的区别?
(1) :first-child
比 :first-of-type
多一个条件:
-
p:first-child
- 父元素下的第一个<p>
元素 且 该元素是父元素下的第一个元素 -
p:first-of-type
- 父元素下的第一个<p>
元素
也即,任何 :first-child
元素一定是 :first-of-type
元素。
(2) 对于一个父元素,:first-child
匹配的最多是一个子元素,而 :first-of-type
可能匹配多个不同的子元素
-
div :first-child
-<div>
元素的第一个子元素 -
div :first-of-type
-<div>
元素的子元素里面每一种元素的第一个,假设有三种子元素<p>
,<a>
,<span>
(个数不限),则会匹配到三个元素。
参考资料:
CSS伪类与伪元素完全指南
总结伪类与伪元素(以上两篇译自/参考自同一篇原文)
详解 CSS 属性 - 伪类和伪元素的区别
Jquery伪类选择器加与不加空格的区别