← 返回文章列表
CSS·854 次阅读

CSS 层叠与优先级:我的样式为什么不生效

CSS 层叠与优先级:我的样式为什么不生效

写 CSS 最挫败的时刻:明明写了样式,页面上就是不生效。打开 DevTools 一看,自己的规则被划掉了,上面盖着一条不知道从哪来的。这背后就是 CSS 的"C"——层叠(Cascade)。

层叠的三道裁判

两条规则冲突时,浏览器按这个顺序裁决:

  1. 来源与重要性:!important > 作者样式 > 浏览器默认样式
  2. 优先级(Specificity):同来源比选择器权重
  3. 书写顺序:权重一样,后写的赢

日常 90% 的"不生效"都卡在第 2 关。

优先级的计算规则

把选择器拆成四档(a, b, c, d),从高到低:

档位 内容 例子
a 行内样式 style="color: red"
b ID 选择器 #nav
c 类、属性、伪类 .btn、[type="text"]、:hover
d 元素、伪元素 div、::before

比较方式是从高档往低档逐级比,高档赢了直接结束:

/* (0,1,0,1) #nav 一个 ID + li 一个元素 */
#nav li { color: red; }

/* (0,0,10,2) 十个类也赢不了一个 ID */
.a.b.c.d.e.f.g.h.i.j div span { color: blue; }

第一条赢。权重不进位,10 个 c 也顶不上 1 个 b,这就是为什么不推荐滥用 ID 选择器写样式——一旦用了 ID,后面想覆盖只能再写更长的 ID 组合或者 !important,开始军备竞赛。

几个容易搞错的:

  • *、组合符(>、+、空格)权重为零,不参与计算
  • :not()、:is() 本身不算权重,但括号里的参数算
  • :where() 是特例:整个选择器权重恒为零,UI 库用它提供可被轻松覆盖的默认样式

!important:掀桌子

.text { color: green !important; }

加上就赢过所有普通声明,行内样式也压不住。唯一能干掉 !important 的是另一个权重更高的 !important——所以它是单行道的尽头,用了就回不了头。

合理的使用场景基本只有:覆盖第三方组件库的行内样式这种你控制不了来源的情况。自己的代码里出现 !important,多半是优先级设计出了问题,应该从选择器结构上解决。

实战排查套路

样式不生效时按这个顺序查:

  1. DevTools 看元素,找到被划掉的那条规则,看赢它的是谁、权重多少、来自哪个文件
  2. 检查选择器是不是没选中——类名拼写、层级对不上(这种 DevTools 里根本不会出现这条规则)
  3. 检查属性本身是否有效:比如给行内元素设 width/height、值写错单位,规则在但声明被丢弃(DevTools 里会有黄色警告图标)
  4. 检查是不是被继承值骗了:color 会继承,background 不会,别搞混

工程上的建议

  • 统一用类选择器(BEM 之类),让所有规则权重保持在同一档,覆盖顺序只由书写顺序决定,可预测
  • 组件库里用 :where() 包默认样式,业务方一个普通类就能覆盖
  • 禁止 !important 进代码规范,除非注释说明在覆盖第三方
  • 嵌套不要太深,三层以内,既是为性能也是为权重可控

层叠机制是 CSS 的设计精髓而不是缺陷,它让样式可以分层组织:库提供默认、主题做覆盖、业务做定制。觉得它"玄学",通常只是还没看清三道裁判的顺序。

看到这里了?如果这篇文章帮到过你

请我喝瓶可乐就好 🥤

收款码

评论0 条

还没有评论,来抢沙发~

发表评论

评论需审核后显示

© 2026 许冬博客 · 专注 JS 技术分享

·RSS 订阅·Powered by Nuxt 4