层叠与继承
层叠与继承
CSS 代表层叠样式表(Cascading Style Sheets),其中层叠与继承的概念十分重要,理解层叠与继承可以让我们更好地将样式应用到页面当中
层叠
层叠是 CSS 一大重要的特性,样式表层叠——简单来说,就是 CSS 样式规则在页面上的应用顺序,即页面上的元素最终会应用哪一条样式规则进行渲染
理解层叠一般从以下三个因素考虑(❗代表重要性):
- 资源顺序 ❗
- 优先级 ❗❗
- 重要程度 ❗❗❗
资源顺序
当超过一条以上的同级别(相同的权重/优先级)的规则应用于同一元素时,写在最后面的规则会被应用,可以理解为后面的规则覆盖前面的规则,直到最后一个开始设置样式
<h1>Hello World!</h1>
h1{
color: red;
}
h1{
color: green; /*绿色生效了,覆盖了前面的红色*/
}
优先级
在一些情况下,有些规则写在最后面,但是却应用了前面的具有冲突的规则。这是因为前面的有更高的优先级——它范围更小,权重更大,因此浏览器就把它选择为元素的样式
样式应用的优先级与选择器的使用息息相关,不同的选择器对应着不同的权重(多个选择器组合使用时,它们的权重是每个同级别选择器的权重相加的结果)。为了便于理解,在这里假设以 ID选择器 所对应的权重为 1-0-0,那么它们的权重排序为:(由大到小)
- ID:ID选择器(权重为 1-0-0)
- 类:选择器中包含类选择器、属性选择器或者伪类(权重为 0-1-0)
- 元素:选择器中包含元素、伪元素选择器(权重为 0-0-1)
<div id='box'>
<p class='text'>this is text1</p>
<span lang='en'>this is text2</span>
</div>
#box .text{
color: green; /* 绿色样式被应用 */
}
div > .text{
color: gray;
}
#box span[lang=en]{
color: red; /* 红色样式被应用 */
}
#box span{
color: yellow;
}
选择器权重的计算示例,权重大的选择器会最终应用其样式
选择器 | ID | 类 | 元素 | 优先级(权重) |
---|---|---|---|---|
#box .text | 1 | 1 | 0 | 1-1-0 |
div > .text | 0 | 1 | 1 | 0-1-1 |
#box span[lang=en] | 1 | 1 | 1 | 1-1-1 |
#box span | 1 | 0 | 1 | 1-0-1 |
通用选择器 (*)、组合符 (+、>、~、' ') 和调整优先级的选择器 (:where()) 不会影响优先级
否定 (:not()) 和任意匹配 (:is()) 伪类本身对优先级没有影响,但它们的参数则会带来影响。参数中优先级计算结果的最大值将作为该伪类选择器的优先级
每一个选择器类编都有它自己的优先级等级,它们不会被具有较低优先级的选择器覆盖。例如,权重为一百万的类选择器不会覆盖权重为一的 ID 选择器。评估优先级的最佳方法是 对不同的优先级等级单独进行评分,并从最高的等级开始,必要时再计算低优先级等级的权重。即,仅当某一列的优先级权重相同时,你才需要评估下一列;否则,你可以直接忽略低等级的选择器,因为它们无法覆盖高优先级等级的选择器
重要程度
影响 CSS 样式规则的应用除了上面的优先级规则外,还有 内联样式 与 !important 这两种声明方式,它们的优先级要高于选择器
内联样式
内联样式,即在元素的 style
属性内的样式声明,优先于所有普通的样式,无论其优先级如何。这样的声明没有选择器,但它们的优先级可以理解为 1-0-0-0;即无论选择器中有多少个 ID,它总是比其他任何优先级的权重都要高
!important
给样式加上 !important
声明可以用来覆盖上面所有优先级计算,不过需要谨慎的使用它——避免某一样式在需要修改时无法应用到最新的样式
<div id='box'>
<p class='text' style='color:blue;'>this is example1</p>
<span lang='en'>this is example2</span>
</div>
#box .text{ /* 内联样式蓝色样式被应用 */
color: green;
}
div > p{
color: gray;
}
#box span[lang=en]{
color: yellow;
}
div span{
color: purple !important; /* 紫色样式被应用 */
}
位置
CSS 声明的优先级还取决于定义它的样式表和级联层,它让用户可以设置自定义样式表来覆盖开发人员定义的样式
如果声明相互冲突,将会按以下顺序进行覆盖:(后面的会覆盖前面的)
- 用户代理样式表中的声明(例如,浏览器的默认样式,在没有设置其他样式时使用)。
- 用户样式表中的常规声明(由用户设置的自定义样式)。
- 作者样式表中的常规声明(这些是我们 web 开发人员设置的样式)。
- 作者样式表中的
!important
声明 - 用户样式表中的
!important
声明 - 用户代理样式表中的
!important
声明
级联层
在级联层中声明的 CSS 的优先级,由声明层的顺序来决定。在任何级联层之外声明的 CSS 样式会被按声明的顺序组合在一起,形成一个未命名的层,它会被当作最后声明的层。
对于存在冲突的常规(没有 !important 声明)样式,后面的层比先前定义的层的优先级高。但对于带有 !important
标记的样式,其顺序相反——先前的层中的 important 样式比后面的层以及为在层中声明的 important 样式优先级要高。但内联样式比所有作者定义的样式的优先级都要高,不受级联层规则的影响
<p class='text'>this is an example</p>
@layer firstLayer, secondLayer;
p { /* 0-0-1 */
color: grey !important;
}
p.text { /* 0-1-1 */
color:blue !important;
}
@layer firstLayer {
.text { /* 0-1-0 */
color: red !important; /* 红色样式被应用了 */
}
}
@layer secondLayer {
p.text { /* 0-1-1 */
color: green !important;
}
}
继承
继承 是 CSS 另一大重要特性,在 CSS 中,每个 CSS 样式都有继承 ("Inherited: Yes") 或者不继承的 ("Inherited: no")的特性。这决定了当没有为元素的属性指定值时页面该如何计算值
继承属性
当元素的一个继承属性没有指定值时,则取父元素的同属性的计算值(只有文档的根元素取该属性的初始值(默认值))
<div id='box'>
<p class='text'>this is an example</p>
</div>
#box{
color:red; /** p元素继承了父元素div的字体颜色的样式 */
}
非继承属性
当元素的一个非继承属性没有指定值时,则取属性的初始值(默认值)
<div id='box'>
<p class='text'>this is an example</p>
</div>
#box{
border:2px dashed orange;/** p元素没有继承父元素div的边框样式,p元素的边框样式默认值为none */
}
控制继承
CSS 为控制继承提供了五个特殊的通用属性值。每个 CSS 属性都接收这些值
属性 | 描述 |
---|---|
inherit | 设置该属性会使子元素属性和父元素相同,相当于“开启继承” |
initial | 将应用于选定元素的属性值设置为该属性的初始值(默认值) |
unset | 将属性重置为自然值,也就是如果属性是自然继承那么就是 inherit ,否则和 initial 一样 |
revert | 将应用于选定元素的属性值重置为浏览器的默认样式,而不是应用于该属性的默认值 |
revert-layer | 将应用于选定元素的属性值重置为在上一个层叠层中建立的值 |
当在项目中,某个元素上面应用的样式太多而更改起来比较复杂时,可以使用 CSS 简写属性 all
来撤销选定元素的样式,可以将 all
属性的值设置为上面表格中的任意一个值,将元素的样式恢复到之前的初始状态
CSS 属性是否继承,在 CSS 属性定义里面就已经设置了,要具体了解某个 CSS 属性是否可以继承,请查阅前一章节或者 MDN