这不是 bug,是 css 层叠规则起作用:按 specificity 和 source order 决定样式生效顺序;父选择器权重更高或声明靠后会覆盖子元素样式。

为什么子元素样式被父元素覆盖了
这不是 bug,是 CSS 层叠规则在起作用:当多个选择器匹配同一个元素时,浏览器按 specificity(权重) 和 source order(声明顺序) 决定谁生效。父元素选择器(比如 .container p)可能比子元素自己写的 p 或 .text 权重更高,或者写在后面覆盖了前面。
怎么快速判断是谁在覆盖
打开 Chrome DevTools → 选中目标子元素 → 看 Computed 面板右侧的 Styles 标签页,被划掉的样式就是被覆盖的;点开对应规则,能看到选择器、文件路径和行号。重点关注:
- 带
!important的声明(优先级最高,但慎用) - 选择器里有没有
id(#header权重远高于.item) - 有没有内联样式(
style="color: red"权重高于所有外部选择器) - 是否用了属性选择器或伪类(
[type="text"]、:hover会增加权重)
不用 !important 的 3 种可靠解法
优先级从高到低排列,推荐按顺序尝试:
-
提高子元素选择器权重:把
.child改成.parent .child或.parent > .child,明确限定上下文 -
利用更具体的父级结构:比如原样式是
section p,子元素想单独控制,就写section.content p.intro—— 多一个 class 就多 10 分权重 -
调整样式表加载顺序:确保子组件样式 CSS 在父组件样式之后引入(HTML 中
<link>位置靠后),同权重时后声明者胜出
容易被忽略的层级陷阱
即使写了正确选择器,也可能因 DOM 结构“意外断层”而失效:
立即学习“前端免费学习笔记(深入)”;
-
.parent > .child只匹配**直接子元素**,如果中间插了个<div>,就选不到 <li> <code>:not()、:is()等现代伪类会影响权重计算,且部分老浏览器不支持 - CSS-in-JS 库(如 styled-components)默认加哈希后缀,实际生成的选择器可能比你写的长得多,导致权重天然更高
- Shadow DOM 内部样式完全隔离,外部选择器根本无法穿透,必须在 shadow root 内定义
真正卡住的时候,别只盯着 CSS 文件,先 inspect 元素看它最终渲染出的 class 名和嵌套关系。








