对于css
,属性值的计算过程是非常核心和重要的。把这个搞定了,那其他的规则就变得很简单了。
属性值的计算过程,指的是 某个元素从所有css属性都没有值,到所有css属性都有值的过程
。
比如说某个div
元素,在最开始运行页面的时候,它所有的属性都没有值,然后经过一系列的运算,变成了每一个css属性都有值.
这时候也许会有疑问,当初我也是,就是一个元素的属性,不是我写哪些它就生效哪些吗,怎么会是所有呢。完全不是这样!!!👏 看一个例子:
html
<template>
<div>hello</div>
</template>
<style lang="scss" scoped>
div{
color: red;
}
</style>
这里只写了一个属性,难道最终只有这一个属性吗?来看看它的计算结果:
它的css属性每一个都得有值,哪怕我们只写了一个属性,它也必须要保证所有的css属性都有值。那么计算过程是怎么计算的呢?共分为四个步骤:
1.确定声明值
比如有这么一个元素,有一个类。
html
<div class="text">hello</div>
刚开始每一个css属性都没有值,那怎么计算呢?首先第一步,确定声明值。
- 作者样式表:我们开发者写的css。
- 浏览器默认样式表:就算什么都不写,浏览器都会默认生成一个样式表。
这些别的样式,就是浏览器默认样式表,也是用户代理样式表(user agent stylesheet)
。
PS: display:block; 称为:变成块盒。像块级元素这种说法已经是10年前的说法了,现在已经没有什么块级元素,行级元素的说法了。css官方明确告诉我们不再使用这种说法了,而是说 默认生成块盒,因为浏览器默认样式表里给它加了
display:block;
这个时候它会观察两个样式表,找到没有冲突的样式作为最终的计算结果。比如作者样式表
里没有写font-size
,则使用浏览器默认样式表
里的作为最终计算结果。另外会把我们设置的预设值
转为为绝对值
,比如说颜色red
,会转为rbg
格式。
2.层叠
层叠这部分是非常重要的,从css的全称层叠样式表
中就可以看出。那它要解决什么呢?解决那些发生冲突的样式,选出最终的一种样式。如果说h1
设置了字体大小,这就和浏览器默认样式表
冲突了。
解决冲突会经过三个步骤:比较重要性、比较特殊性、比较源次序。
1. 比较重要性
重要性从高到低:
- 带有
important
的作者样式; - 带有
important
的默认样式; - 作者样式;
- 默认样式;
2. 比较特殊性
这也就是大家常说的权重
了。它要计算每个冲突的样式的特殊性的值是多少。 要从style、id、属性、元素
四个方面去比较。
style | id | 属性 | 元素 |
---|---|---|---|
内联:1;外联:0 | id选择器的数量 | 属性、类、伪类的数量 | 元素、伪元素的数量 |
例如:
css
.text {
color: red;
font-size: 40px;
}
h1 {
font-size: 26px;
}
div h1.text {
font-size: 14px;
font-size: 30px;
}
这里的font-size
冲突了,那我们就来计算它的4个值
。
- .test
不是内联样式,0;id选择器数量为0,0;有一个类选择器,1;没有元素选择器,0。结果是 0010。
- h1
不是内联样式,0;id选择器数量为0,0;没有类选择器,0;有一个元素选择器,1。结果是 0001。
- div h1.text
不是内联样式,0;id选择器数量为0,0;有一个类选择器,1;有两个元素选择器,1。结果是 0012。
把所有冲突的样式的特殊性的四个值算出来,然后从高位到地位进行比较。通过比较,胜出的是最后一组。
3. 比较源次序
如果还有冲突就比较源次序,就是比较源代码里面的书写顺序,哪个书写的靠后,就用哪一个。上面的字体14
和30
冲突了,因为30
靠后,所以最终结果是它。
3.继承
继承的发生是有条件的,得满足以下两个条件。
- 目前是仍然没有值的。
- 是可以继承的。
满足这两个就ok了,那哪些是可以被继承的呢?有一个粗略的规则,就是和文字相关的是可以继承的,例如行高,字体大小,字体颜色。和文字不相关的是不可以继承的,例如宽高、位置。 如果要详细知道,那就去MDN
查看该属性的具体信息。
4.使用默认值
那么多的css属性,我们书写的时候也没写那么多,不冲突就用我们写的;冲突了就根据层叠规则来。还没写的,比如text-align
,就继承了。那还剩很多,比如background-color
这种怎么办,那这时候就使用它的默认值了。同理,默认值可以查看MDN
,这里以 background-color为例
经过了这四个步骤,保证每个元素的css属性都有值。在这四个步骤当中,继承
和使用默认值
是动不了的,我们写的代码只能影响到确定声明值
与层叠
。
来看一个小例子:
html
<div class="box">
<p>这时一句话</p>
<a href="">这时一个链接</a>
</div>
给box
设置了颜色:
css
<style>
.box {
color: pink;
}
</style>
p
元素的颜色是对了,但a
元素并没有。我们没有对a
进行操作,所以要么是继承
要么使用默认值
,打开浏览器就会发现a
元素有默认值。而对于p
,没有默认值
,所以继承
了父元素。、