CSS 选择器

HTML Element 作为一种数据,被处理首先需要获取它,在 DOM API 中使用 getElementById 等一系列方法获取,而在 CSS 中使用选择器来获取。

选择器分类和妙用

选择器分类

  • 基本选择器
1
2
3
4
5
* 通用选择器
E 标签选择器
类选择器
ID 选择器
属性选择器

其中属性选择器又分为:

1
2
3
4
5
6
7
[attr]
[attr=val]
[attr|=val] 开头匹配(分词)
[attr~=val] 包含匹配(分词)
[attr^=val] 开头匹配
[attr$=val] 结尾匹配
[attr*=val] 包含匹配

注:多个选择器,不加任何空格连接在一起,可实现选择器的交集。

1
2
3
4
5
6
7
E.class {}
:hover {}
E:hover {}
[attr] {}
E[attr] {}
:first-child {}
E:first-child {}
  • 分组选择器

使用 , 将不同选择器组合在一起,实现多个元素的选择。

1
E,F {}
  • 关系选择器

关系选择器也叫组合选择器。

1
2
3
4
E F 后代选择器
E>F 子选择器
E~F 相邻选择器
E+F 相邻兄弟选择器
  • 伪类选择器
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
36
37
38
39
40
41
42
43
44
45
* 语言的伪类
:lang

* 输入状态伪类
:enabled
:disabled
:checked
:read-only
:read-write
:required
:optional
:valid
:inlvalid
:in-range
:out-of-range

* 位置伪类
:link
:visited
:target

* 树结构伪类
:root
:empty, E 元素中没有子节点(包含文本节点)
:first-child
:last-child
:first-of-type
:last-of-type
:nth-child(n), 父元素中的第 n 个 E 元素,选择父元素下的所有子元素中满足指定规律的元素,不考虑元素的类型,如果不带父选择器,则从所有存在父子关系的子元素中选择
:nth-last-child(n), 父元素中的第 n 个 E 元素,从后向前计算
:nth-of-type(n), 选择相同类型(标签名称)的兄弟元素中指定规律的元素
:nth-last-of-type(n)
:only-of-type
:only-child

* 用户行为伪类
:hover
:active
:focus

* 函数式伪类
:not()
:has()
:is()
:where()

注:带 type 的选择器,是在相同类型(相同标签名称)中进行选择的,比如,first-of-type 即相同标签类型中的第一个、only-of-type 即相同标签中唯一。

  • 伪元素选择器
1
2
3
4
5
::before 原始的开始
::after 元素的结尾
::first-letter 第一个字母
::first-line 第一行
::selecton 选中的内容

伪元素表示的是并不真实存在的元素(特殊的位置),与伪类的主要区别是,伪类选择的是元素,而伪元素选择器选择的是伪元素。

选择器的妙用

  • :nth-child()
1
2
3
4
5
// 奇偶选择
E:nth-child(odd)
E:nth-child(even)
E:nth-child(2n)
E:nth-child(2n+1)
1
2
3
4
5
6
7
// 范围选择
// 选择 3 开始的元素
li:nth-child(-n+3) {}
// 选择 13 的元素
li:nth-child(-n+3) {}
// 选择 36 的元素
li:nth-child(n+3):nth-child(-n+6) {}
1
2
// 周期选择
nth-child(an+b) // a为步长,b为偏移量

注:n0 开始的非负整数。

  • :not()

not 被用来反选。

1
2
li:not(:nth-child(-n+3)) {}
li:not(:last-child) {}
1
2
3
4
5
// 选择除最后一个 li 外的所有 li
// 逗号分隔列表
ul > li:not(:last-child)::after {
content: ",";
}
  • :empty
1
2
3
4
// 当 a 元素没有文本内容,但有 href 属性的时候,显示它的 href 属性
a[href^="http"]:empty::before {
content: attr(href);
}
  • :has()

使用 has 实现父选择器:

1
2
// 选择包含 .child 子元素的 .parent 父元素
.parent:has(.child) {}

选择器的权重

选择器的权重被分为三级 a.b.c,其中,通配符选择器 0,标签选择器、伪元素 1,类、伪类、属性选择器 10,id 选择器 100

1
2
3
4
5
6
7
8
9
* {} // 0
p em {} // 2
#wrap .waring {} // 110
li:first-line {} // 2
ul ol+li {} // 3
h1+*[rel=up] {} // 11(一个属性选择器,一个标签)
a[id="a-02"] {} // 11(一个属性选择器,一个标签)
body #content .data img:hover {} // 122
p.note em.dark {} // 22
1
2
<div class="red"><div class="green"><p>1. 颜色是?</p></div></div>
<div class="green"><div class="red"><p>1. 颜色是?</p></div></div>
1
2
.red {color: red;}
.green {color: green;}
1
2
.red p{color: red;}
.green p{color: green;}
1
2
:not(.green) p {color: red;}
.green p {color: green;}

:not(.green) 伪选择器的“位”权重与 .green 是一样的,最后按顺序进行解析。

另外,需要注意的是 Inline Style 优先级高于 stylelink,被 !important 修饰的属性拥有最高的优先级。

注:使用 specificity 工具可以计算权重,可在线使用。