CSS伪类选择器详解

什么是伪类选择器

CSS伪类选择器用于选择元素的特定状态或结构位置,使用单个冒号(:`)作为前缀。伪类选择器允许我们根据元素的动态状态或在文档树中的位置来应用样式,而不仅仅是基于元素的类型、类名或ID。

伪类选择器的分类

根据使用场景的不同,伪类选择器可以分为以下几类:

  1. 状态伪类:根据元素的动态状态选择
  2. 结构伪类:根据元素在文档树中的位置选择
  3. 表单伪类:针对表单元素的状态选择

1. 状态伪类选择器

状态伪类选择器用于选择元素在特定状态下的样式,主要包括链接伪类和用户行为伪类。

1.1 链接伪类

链接伪类用于根据链接的不同状态(如未访问、已访问、悬停、点击等)为其添加样式。

伪类 描述 示例
:link 未访问的链接 a:link { color: blue; }
:visited 已访问的链接 a:visited { color: purple; }
:hover 鼠标悬停在链接上 a:hover { color: red; }
:active 链接被点击时的瞬时状态 a:active { color: orange; }

链接伪类的顺序规则(LVHA顺序)

使用链接伪类时,必须按照特定的顺序书写才能确保样式正确应用,即:a:linka:visiteda:hovera:active

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 正确的链接伪类顺序 */
a:link {
color: #3498db;
text-decoration: none;
}

a:visited {
color: #9b59b6;
}

a:hover {
color: #e74c3c;
text-decoration: underline;
}

a:active {
color: #f39c12;
}

1.2 用户行为伪类

用户行为伪类用于选择用户与元素交互时的状态。

伪类 描述 示例
:hover 鼠标悬停在元素上 button:hover { background-color: #2ecc71; }
:focus 元素获得焦点(主要用于表单元素) input:focus { border-color: #3498db; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* 按钮悬停效果 */
.btn {
background-color: #3498db;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
transition: background-color 0.3s;
}

.btn:hover {
background-color: #2980b9;
}

/* 输入框焦点效果 */
.input {
padding: 8px;
border: 1px solid #ddd;
outline: none;
}

.input:focus {
border-color: #3498db;
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
}

2. 结构伪类选择器

结构伪类选择器用于根据元素在文档树中的位置来选择目标元素。

伪类 描述 示例
:first-child 一组兄弟元素中的第一个元素 ul li:first-child { font-weight: bold; }
:last-child 一组兄弟元素中的最后一个元素 ul li:last-child { margin-bottom: 0; }
:nth-child(n) 一组兄弟元素列表中第n个元素 ul li:nth-child(3) { color: red; }
:nth-last-child(n) 一组兄弟元素列表中倒数第n个元素 ul li:nth-last-child(2) { color: blue; }
:first-of-type 同类型元素中的第一个 div p:first-of-type { font-size: 1.2em; }
:last-of-type 同类型元素中的最后一个 div p:last-of-type { margin-bottom: 0; }
:nth-of-type(n) 同类型元素中的第n个 div p:nth-of-type(2) { color: green; }
:nth-last-of-type(n) 同类型元素中倒数第n个 div p:nth-last-of-type(3) { color: purple; }
:only-child 父元素中唯一的子元素 div:only-child { margin: 0 auto; }
:only-of-type 父元素中唯一的该类型元素 div p:only-of-type { font-style: italic; }
:empty 没有子元素(包括文本节点)的元素 div:empty { display: none; }

:nth-child(n) 的特殊取值

n 可以是:

  • 数字:从1开始计数
  • 关键字:odd(奇数)、even(偶数)
  • 公式:an+b,其中 ab 是整数,n 从0开始计数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* 选择奇数行 */
tr:nth-child(odd) {
background-color: #f5f5f5;
}

/* 选择偶数行 */
tr:nth-child(even) {
background-color: #fff;
}

/* 选择前3个元素 */
li:nth-child(-n+3) {
color: red;
}

/* 选择第2个及以后的元素 */
li:nth-child(n+2) {
margin-top: 10px;
}

/* 选择3的倍数元素 */
li:nth-child(3n) {
border-right: 2px solid #ddd;
}

/* 选择3n+1的元素(第1、4、7...个) */
li:nth-child(3n+1) {
font-weight: bold;
}

3. 表单伪类选择器

表单伪类选择器用于针对表单元素的特定状态进行样式设置。

伪类 描述 示例
:disabled 禁用的表单元素 input:disabled { background-color: #f0f0f0; }
:enabled 可用的表单元素 input:enabled { border-color: #ddd; }
:checked 选中状态的单选按钮或复选框 input:checked + label { color: #3498db; }
:required 必填的表单元素 input:required { border-left: 3px solid #e74c3c; }
:optional 可选的表单元素 input:optional { border-left: 3px solid #2ecc71; }
:valid 验证通过的表单元素 input:valid { border-color: #2ecc71; }
:invalid 验证失败的表单元素 input:invalid { border-color: #e74c3c; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/* 禁用状态的按钮 */
button:disabled {
background-color: #bdc3c7;
cursor: not-allowed;
color: #7f8c8d;
}

/* 选中状态的复选框 */
input[type="checkbox"]:checked + label {
color: #2ecc71;
font-weight: bold;
}

/* 表单验证样式 */
.input {
padding: 8px;
border: 1px solid #ddd;
outline: none;
}

.input:valid {
border-color: #2ecc71;
}

.input:invalid {
border-color: #e74c3c;
}

/* 必填项样式 */
.input:required {
background-image: url("required-icon.png");
background-repeat: no-repeat;
background-position: right center;
padding-right: 20px;
}

伪类选择器的优先级

伪类选择器的优先级与类选择器相同,高于标签选择器,低于ID选择器。当多个伪类选择器应用于同一个元素时,遵循CSS优先级规则,即:

  1. 内联样式 > ID选择器 > 类选择器/伪类选择器 > 标签选择器
  2. 优先级相同时,后定义的样式覆盖先定义的样式

浏览器兼容性

大部分伪类选择器(如:link:visited:hover:active:focus:first-child:last-child)在现代浏览器中都有良好的支持,包括IE8+。

对于一些较新的伪类选择器(如:nth-child():nth-of-type():checked:disabled等),IE9+及所有现代浏览器都支持。

最佳实践

  1. 合理使用伪类:根据实际需求选择合适的伪类,避免过度使用复杂的伪类选择器
  2. 注意性能:复杂的结构伪类选择器(如:nth-child(n))可能会影响页面性能,尤其是在大型页面中
  3. 保持语义化:伪类选择器应增强语义,而不是替代语义化HTML
  4. 结合过渡效果:为伪类添加过渡效果(transition)可以使状态变化更加平滑,提升用户体验
  5. 测试兼容性:在目标浏览器中测试伪类选择器的效果,确保兼容性

总结

  • 定义:伪类选择器用于选择元素的特定状态或结构位置,使用单个冒号(:)作为前缀
  • 分类
    • 状态伪类::link:visited:hover:active:focus
    • 结构伪类::first-child:last-child:nth-child(n):nth-of-type(n)
    • 表单伪类::disabled:enabled:checked:required:valid:invalid
  • 链接伪类顺序:LVHA顺序(:link:visited:hover:active
  • :nth-child(n) 特殊取值
    • 数字:直接指定位置
    • 关键字:odd(奇数)、even(偶数)
    • 公式:an+b(如 3n 表示3的倍数)
  • 优先级:与类选择器相同(10)
  • 最佳实践
    • 合理使用,避免过度复杂的结构伪类
    • 结合过渡效果提升用户体验
    • 注意浏览器兼容性
    • 保持语义化