网站

CSS 层叠与继承 | MDN

CSS 参考手册

引入

同一个元素可能会被多条 CSS 规则同时选中。

层叠规则用来决定:当多个样式发生冲突时,浏览器最终使用哪一条样式。

正文

定义

定义

CSS 层叠规则是浏览器在多条样式同时作用于同一个元素时,用来决定最终样式的计算规则。

CSS 不是简单地“谁先写谁生效”。

它会综合考虑样式来源、!important、选择器优先级、书写顺序等因素。

基本判断顺序

常见情况下,可以先按这个顺序理解:

  1. !important 权重很高
  2. 内联样式通常高于普通选择器
  3. id 选择器高于 class 选择器
  4. class、伪类、属性选择器高于元素选择器
  5. 优先级相同时,后写的覆盖先写的

例子

<p id="intro" class="text">这是一段文字</p>
p {
  color: black;
}
 
.text {
  color: blue;
}
 
#intro {
  color: red;
}

最终文字颜色是红色。

因为 #introid 选择器,优先级高于 .textp

样式来源

CSS 样式可能来自不同地方。

来源说明
浏览器默认样式浏览器自带的基础样式
用户样式用户自己设置的样式
作者样式开发者写的 CSS
内联样式写在元素 style 属性中的样式

平时写网页时,最常接触的是作者样式和内联样式。

<p style="color: red;">这是一段文字</p>

这个 style 属性中的样式通常会比外部 CSS 中的普通选择器优先级更高。

选择器优先级

选择器优先级可以简单理解为:选得越具体,优先级通常越高。

选择器示例优先级理解
内联样式style="color: red;"很高
id 选择器#app
class 选择器.card
伪类:hover
属性选择器[type="text"]
元素选择器p
通用选择器*很低

例如:

p {
  color: black;
}
 
.content p {
  color: blue;
}

如果 p.content 里面,最终会使用 color: blue;

因为 .content p 比单独的 p 更具体。

书写顺序

如果两条规则优先级相同,后写的会覆盖先写的。

.text {
  color: blue;
}
 
.text {
  color: red;
}

最终 .text 的文字颜色是红色。

这不是因为红色更特殊,而是因为第二条 .text 写在后面。

!important

!important 可以强行提高某条声明的优先级。

.text {
  color: red !important;
}
 
#intro {
  color: blue;
}

即使 #intro 的选择器优先级更高,最终也可能使用 color: red;

因为 .text 里的声明加了 !important

继承和层叠

有些 CSS 属性会被子元素继承,例如 colorfont-sizefont-family

.article {
  color: #333333;
}

.article 里面的文字通常会继承这个颜色。

但如果子元素自己设置了颜色,就会使用自己的样式。

.article a {
  color: blue;
}

继承得到的样式,一般不如直接选中元素设置的样式强。

常见属性

关键词作用
inherit强制继承父元素的值
initial使用属性的初始值
unset如果属性可继承就继承,否则使用初始值
revert回退到浏览器或用户样式

示例:

.link {
  color: inherit;
}

这里 .link 会继承父元素的文字颜色。

特点

  • 层叠规则用于解决样式冲突
  • 优先级高的规则会覆盖优先级低的规则
  • 优先级相同时,后写的样式覆盖先写的样式
  • !important 很强,但不建议随便使用
  • 继承来的样式通常不如直接设置的样式优先
  • 选择器写得越复杂,不一定越好维护

注意事项

  • 不要为了覆盖样式一直加 !important
  • 不要把选择器写得过深,例如 .a .b .c .d p
  • 公共样式尽量保持简单,组件样式再写具体一些
  • 遇到样式不生效时,先检查选择器是否选中了元素,再检查优先级和书写顺序

理解

可以把层叠规则理解为 CSS 的“裁判”。

当多个规则都想控制同一个元素时,浏览器会按照固定规则判断谁更有资格生效。

写 CSS 时,不只是要知道某个属性怎么写,还要知道这条规则能不能赢过其他规则。

引出

理解层叠规则之后,再看 CSS 优先级CSS 选择器 和组件样式覆盖问题会更清楚。