CSS 选择器
- 用于匹配 HTML 元素。选择器所选择的元素,叫做"选择器的对象"
- 分类和权重
- 解析方式和性能
- 值得关注的选择器
CSS 选择器解析方式
CSS 选择器解析是指浏览器在渲染页面时,如何解析 CSS 选择器以确定哪些元素应该应用 CSS 样式。
- 在解析选择器时,浏览器按从右到左的顺序进行匹配,以尽早确定是否匹配。
- 比如,当解析后代选择器
div p时,浏览器会先找到所有p元素,然后再检查它们是否是div元素的后代。 - 如果选择器包含了 ID 或者 class 等属性选择器,则浏览器会先找到拥有该属性的元素。
CSS 选择器性能
CSS 选择器的性能与选择器的复杂度和页面结构有关。选择器越复杂,匹配所需的计算量就越大,因此影响性能的因素有:
- 选择器的复杂度:选择器中包含的规则越多,匹配所需的计算量就越大。因此,应该尽量避免使用嵌套、通配符、后代选择器等复杂选择器。
- 文档结构:文档结构越复杂,匹配所需的计算量就越大。如果文档层次结构较深,选择器中的后代选择器会导致匹配的计算量增加。
- 样式数量:当页面中包含大量的样式规则时,浏览器需要更多的计算来确定哪些样式应该应用于元素。因此,应该尽量避免使用冗余或不必要的样式规则。
- 缓存:浏览器会缓存已解析的样式规则,以便在后续的页面加载中加快渲染速度。因此,使用相同的选择器多次可以提高性能。
综上所述,为了提高 CSS 选择器的性能,应该尽量避免使用复杂的选择器,优化文档结构,避免冗余或不必要的样式规则,并尽可能使用已缓存的样式规则。
CSS 选择器分类
通用选择器(Universal selector):选择所有元素。(可选)可以将其限制为特定的名称空间或所有名称空间。
- 语法:
*ns|**|* - 例子:
*将匹配文档的所有元素。
- 语法:
元素选择器(Type selector):按照给定的节点名称,选择所有匹配的元素。
- 语法:
elementname - 例子:
input匹配任何<input>元素。
- 语法:
类选择器(Class selector):按照给定的
class属性的值,选择所有匹配的元素。- 语法:
.classname - 例子:
.index匹配任何class属性中含有 "index" 类的元素。
- 语法:
ID 选择器(ID selector):按照
id属性选择一个与之匹配的元素。需要注意的是,一个文档中,每个 ID 属性都应当是唯一的。- 语法:
#idname - 例子:
#toc匹配 ID 为 "toc" 的元素。
- 语法:
属性选择器(Attribute selector):按照给定的属性,选择所有匹配的元素。
- 语法:
[attr][attr=value][attr~=value][attr|=value][attr^=value][attr$=value][attr*=value] - 例子:
[autoplay]选择所有具有autoplay属性的元素(不论这个属性的值是什么)。
- 语法:
选择器列表(Selector list):
,是将不同的选择器组合在一起的方法,它选择所有能被列表中的任意一个选择器选中的节点。- 语法:
A, B - 示例:
div, span会同时匹配<div>元素和<span>元素。
- 语法:
后代组合器(Descendant combinator):" "(空格)组合器选择前一个元素的后代节点。
- 语法:
A B - 例子:
div span匹配所有位于任意<div>元素之内的<span>元素。
- 语法:
直接子代组合器(Child combinator):
>组合器选择前一个元素的直接子代的节点。- 语法:
A > B - 例子:
ul > li匹配直接嵌套在<ul>元素内的所有<li>元素。
- 语法:
一般兄弟组合器(General sibling combinator):
~组合器选择兄弟元素,也就是说,后一个节点在前一个节点后面的任意位置,并且共享同一个父节点。- 语法:
A ~ B - 例子:
p ~ span匹配同一父元素下,<p>元素后的所有<span>元素。
- 语法:
紧邻兄弟组合器(Adjacent sibling combinator):
+组合器选择相邻元素,即后一个元素紧跟在前一个之后,并且共享同一个父节点。- 语法:
A + B - 例子:
h2 + p会匹配所有紧邻在<h2>元素后的<p>元素。
- 语法:
列组合器(Column combinator):
||组合器选择属于某个表格行的节点。- 语法:
A || B - 例子:
col || td会匹配所有<col>作用域内的<td>元素。
- 语法:
伪类:
:伪选择器支持按照未被包含在文档树中的状态信息来选择元素。- 例子:
a:visited匹配所有曾被访问过的<a>元素。
- 例子:
伪元素:
::伪选择器用于表示无法用 HTML 语义表达的实体。- 例子:
p::first-line匹配所有<p>元素的第一行。
- 例子:
选择器权重
!important 声明,具有最高优先级,其权重为 999999。
内联样式(通过 style 属性定义的样式),其权重为 1000。
ID 选择器
#id{},其权重为 100类选择器、属性选择器、伪类选择器和关系选择器的组合,其权重为 10
元素 伪元素,其权重为 1
其它选择器 (通配符选择器*和继承的样式),其权重为 0
具有相同的选择器权重,则最后定义的规则将覆盖先前定义的规则
选择器权重计算
#id .link a[href] : 结果 111
#id+100.link+10a+1[href]+0
#id .link.active:结果 120
#id+100.link+10.active+10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>basic</title>
<style>
#test1 {
color: red;
}
#test1.test1 {
color: blue;
}
.test2 {
color: red;
}
div.test2 {
color: blue;
}
#test3 {
color: red;
}
.c1.c2.c3.c4.c5.c6.c7.c8.c9.c10.c11 { // 这里类选择器在计算权重时不进位,因为它们之间没有使用空格或其他组合符号分隔
color: blue;
}
</style>
</head>
<body class="body" id="body">
<div id="test1" class="test1">test1</div>
<div class="test2">test2</div>
<div id="test3" class="c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11">test3</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>basic</title>
<style>
#test1 {
color: red;
}
#test1.test1 {
color: blue;
}
.test2 {
color: red;
}
div.test2 {
color: blue;
}
#test3 {
color: red;
}
.c1.c2.c3.c4.c5.c6.c7.c8.c9.c10.c11 { // 这里类选择器在计算权重时不进位,因为它们之间没有使用空格或其他组合符号分隔
color: blue;
}
</style>
</head>
<body class="body" id="body">
<div id="test1" class="test1">test1</div>
<div class="test2">test2</div>
<div id="test3" class="c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11">test3</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>basic</title>
<style>
.test1{
color: red;
}
.test1{
color: blue;
}
.test2{
color: red !important;
}
.test2{
color: blue;
}
#test3{
color: red;
}
</style>
</head>
<body class="body" id="body">
<div class="test1">test1</div>
<div class="test2">test2</div>
<div id="test3" style="color: blue">
test3
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>basic</title>
<style>
.test1{
color: red;
}
.test1{
color: blue;
}
.test2{
color: red !important;
}
.test2{
color: blue;
}
#test3{
color: red;
}
</style>
</head>
<body class="body" id="body">
<div class="test1">test1</div>
<div class="test2">test2</div>
<div id="test3" style="color: blue">
test3
</div>
</body>
</html>