网页最终呈现的样子是各类CSS声明最终叠加到一块儿的效果,咱们如下面的HTML文档为例:css
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<style> h1 { font-size: 20px; } </style>
</head>
<body>
<h1 style="font-size: 10px">h1 title</h1>
</body>
</html>
复制代码
稍微有点HTML和CSS基础的人都能看出,h1最终呈现的字体大小是10px,由于内联样式的优先级更高。html
打开Chrome开发工具,能够看到对h1的字体大小有三处声明。浏览器决定最终采用的哪一个值,是经过各类考量的。各处声明的PK过程咱们称之为层叠。PK的胜负由如下三个方面决定:浏览器
咱们下面对这三个方面逐一讨论。工具
这里的来源指的是CSS声明在哪里?CSS标准中将Origin分为三大主类:开发工具
根据来源,浏览器评判出了声明的重要性(Importance)。评判标准很简单:字体
在层叠PK中,若是相同的选择器重要性不一样,那么Origin这一层的PK就决出了胜负。网站
以下例子:spa
在Origin这一层的PK中:翻译
1号是User的普通申明; 2号选手是用户的!important声明; 3号选手是User agent的普通声明 因此 2号胜出 👏 👏 👏 👏代理
若是两个属性的声明重要性不分上下,这时候该PK特殊性了,特殊性是对选择器而言的。
w3标准里面这样描述特殊性的计算:
A selector’s specificity is calculated for a given element as follows:
- count the number of ID selectors in the selector (= A)
- count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= B)
- count the number of type selectors and pseudo-elements in the selector (= C)
- ignore the universal selector
翻译并本身组织语言以下:
一个选择器的特殊性这样计算:
统计ID选择器的数量(记为A)
统计类选择器、属性选择器、伪类选择器的数量(记为B)
统计元素选择器和伪元素选择器的数量(记为C)
这里推荐一个在线计算选择器Specificity的网站:specificity.keegan.st/
咱们用一个三元组来记录一个选择器的特殊性,例如:
ul ----> (0, 0, 1)
ul, ul ----> (0, 0, 2)
#list ----> (1, 0, 0)
#list #sub-list li ---> (2, 0, 1)
#list .list-item ---> (1, 1, 0)
复制代码
那么获得三元组以后怎么比较两个三元组的优先级呢?
一样举个🌰:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<style> h1 { color: green; } h1#title { color: red; } h1.title { color: blue; } </style>
</head>
<body>
<h1 id="title" class="title">h1 title</h1>
</body>
</html>
复制代码
h1最终呈现的样子是红色:
在上面三条声明中,选择器对应的特殊性以下:
选择器组 | ID选择器数量 | 类或属性选择器数量 | 元素或伪类选择器数量 | 特殊性 | 结果 |
---|---|---|---|---|---|
h1#title | 1 | 0 | 1 | (1, 0, 1) | 👏👏👏 |
h1.title | 0 | 1 | 1 | (0, 1, 1) | 💔 |
h1 | 0 | 0 | 1 | (0, 0,) | 💔 |
无需多言,前两轮PK没有结果的按照出场前后顺序后来居上,决定最终胜负。
有CSS声明的元素退场了,没有CSS声明的只能靠继承或者默认样式了。
某些样式声明会继承到子元素(如颜色、字体大小),有些则不会(如border等)。
CSS 层叠是考虑样式来源、选择器的特殊性、以及继承来决定最终效果的过程。