继承
子元素会继承父元素的某些css属性。这也意味着有着继承的“连锁反应”,即后代元素会继承祖先元素。
这里的“某些”css属性,严格来说要一个个列出来,但那样不利于记忆,我们可以从整体上了解为:通常,跟文字相关的属性会被继承,如color
、font-size
、font-family
、font-weight
等。
所以一个网页中的字体一般是统一的,字体会被设置在<body>标签中。
一个属性是否是继承属性可以在MDN查询,如color的页面中有写到:
插曲小tip:简写属性
如font就是一个简写属性,即一次性定义多个属性。其实这就是一个语法糖。
属性值的计算过程
其实讲的就是页面渲染的过程。
浏览器渲染元素是一个元素一个元素依次渲染的,顺序是遍历html文档的树形目录结构,如图:
渲染每个元素的前提条件:该元素的所有CSS属性必须有值。不是说我们写了哪些属性,就只要哪些属性有值就行了,必须是全部的属性都得有值。比如在浏览器的元素审查界面,可以看到:
一个元素,从所有属性都没有值,到所有属性都有值,就是属性值的计算过程。
属性值计算的四个步骤
1)确定声明值
开发者写的一些样式就是声明值。参考样式表中没有冲突的声明,直接拿来作为属性值。
2)层叠冲突
对样式表有冲突的声明,使用层叠规则,确定属性值。
层叠就是发生在这一步。
3)使用继承
对于还是没有值的属性,继承父元素的值。
继承就是发生在这一步。
4)使用默认值
剩下的没有值的属性就使用默认值,这个默认值是多少可以在MDN查询。
如width的默认值是auto
:
根据属性值的计算过程,现在我们来提一个问题:
Question
代码如下:
div{
color: red;
}
<div>
<a href=""> a元素 </a>
<span> span元素 </span>
</div>
问:a元素是不是红色?
如果你想着:“因为a元素是div的子元素,所以根据继承的规则,a元素应该是红色”,然后回答“Yes”,那么说明你没搞懂属性值的计算过程。
眼见为实:
来解释一下。要确定a元素属性的值要经过前已述及的四个步骤:确定声明值、层叠冲突、使用继承、使用默认值。
对于<span>
元素:
第一步,声明值,span元素没有<span style="color: red">
、span{ color: red; }
这样的声明值,第一步没有赋值。
第二步,层叠,层叠是发生在有声明冲突的时候的,但span元素连声明都没有,哪来的冲突,所以第二步也没有赋值。
第三步,继承,这一步就把<div>
的红色继承了过来,赋值成功。
对于<a>
元素:
第一步确定声明值,这里虽然我们开发者没有写声明值,但浏览器默认样式表中有默认声明值:
所以第一步就确定了颜色属性的值,赋值完成,不再进行后续步骤,所以“继承”这一步没有作用。
那么现在我们希望使用重置样式表覆盖浏览器的默认样式,比如希望<a>
元素没有下划线,颜色继承父元素。
<link rel="stylesheet" href="./css/reset.css">
<div>
<a href=""> a元素 </a>
<span> span元素 </span>
</div>
reset.css:
div{
color: red;
}
a{
text-decoration: none;
color: inherit;
}
这时因为有样式声明冲突,在层叠这一步,我们的作者样式表就会胜出,所以就用我们设置的CSS属性值了。
但是继承是层叠的下一步,如果我们在作者样式表reset.css中赋值color,在层叠这一步就会确定属性值了,那样就无法继承了,所以这里color
的取值为inherit
,表示强制继承、手动继承。
除了inherit
以外还有一个特殊的属性取值:initial
,即默认值,也常用到。