跳至主要內容

层叠与继承

wzCoding大约 8 分钟CSS层叠与继承

层叠与继承

CSS 代表层叠样式表(Cascading Style Sheets),其中层叠与继承的概念十分重要,理解层叠继承可以让我们更好地将样式应用到页面当中

层叠

层叠是 CSS 一大重要的特性,样式表层叠——简单来说,就是 CSS 样式规则在页面上的应用顺序,即页面上的元素最终会应用哪一条样式规则进行渲染

理解层叠一般从以下三个因素考虑(❗代表重要性):

  1. 资源顺序 ❗
  2. 优先级 ❗❗
  3. 重要程度 ❗❗❗

资源顺序

当超过一条以上的同级别(相同的权重/优先级)的规则应用于同一元素时,写在最后面的规则会被应用,可以理解为后面的规则覆盖前面的规则,直到最后一个开始设置样式

代码示例
<h1>Hello World!</h1>
h1{
  color: red;
}
h1{
  color: green; /*绿色生效了,覆盖了前面的红色*/
}

优先级

在一些情况下,有些规则写在最后面,但是却应用了前面的具有冲突的规则。这是因为前面的有更高的优先级——它范围更小,权重更大,因此浏览器就把它选择为元素的样式

样式应用的优先级与选择器的使用息息相关,不同的选择器对应着不同的权重(多个选择器组合使用时,它们的权重是每个同级别选择器的权重相加的结果)。为了便于理解,在这里假设以 ID选择器 所对应的权重为 1-0-0,那么它们的权重排序为:(由大到小)

  1. ID:ID选择器(权重为 1-0-0
  2. 类:选择器中包含类选择器、属性选择器或者伪类(权重为 0-1-0
  3. 元素:选择器中包含元素、伪元素选择器(权重为 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 .text1101-1-0
div > .text0110-1-1
#box span[lang=en]1111-1-1
#box span1011-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 声明的优先级还取决于定义它的样式表和级联层,它让用户可以设置自定义样式表来覆盖开发人员定义的样式

如果声明相互冲突,将会按以下顺序进行覆盖:(后面的会覆盖前面的)

  1. 用户代理样式表中的声明(例如,浏览器的默认样式,在没有设置其他样式时使用)。
  2. 用户样式表中的常规声明(由用户设置的自定义样式)。
  3. 作者样式表中的常规声明(这些是我们 web 开发人员设置的样式)。
  4. 作者样式表中的 !important 声明
  5. 用户样式表中的 !important 声明
  6. 用户代理样式表中的 !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 @rule 创建,创建级联层的方法为:

  1. @layer xxx {}
  2. @import(xxx.css) layer(xxx)
  3. @layer xxx

更多关于级联层的信息请 点击这里

继承

继承 是 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