样式覆盖失效主因是选择器权重不足或加载顺序靠后;需用开发者工具检查Styles面板中带删除线的规则及Computed面板中最终生效来源,优先提升选择器特异性而非滥用!important。

样式覆盖失效,基本就是选择器权重(specificity)没赢,或者加载顺序没卡准。别急着加 !important,先看浏览器开发者工具里那条规则是不是被划掉了。
怎么看哪条样式被覆盖了
打开开发者工具(F12),选中目标元素,在「Styles」面板里找带删除线(strikethrough)的声明——那就是被干掉的;点开「Computed」面板,直接看到最终生效的值和它来自哪条规则、哪个文件、哪一行。
- 被划掉但出现在 Styles 里 → 权重不够,被更高 specificity 的规则压了
- 根本没出现该规则 → 选择器没匹配上(比如写了
input:disabled却作用在button上) - 出现但值不对 → 可能被继承值、UA 样式或
all: unset干扰
权重怎么算:不是“谁在后面谁赢”,是四元组比大小
CSS 权重是个四元组 (a,b,c,d),从左到右逐位比较,大者胜出:
-
a:内联样式数(),几乎不用管,除非你真写了 -
b:ID 选择器个数,如#header→ +100 -
c:类 / 属性 / 伪类个数,如.btn、[type]、:hover、:disabled→ 各 +10 -
d:标签 / 伪元素个数,如div、::before→ 各 +1
例如:form#search input[type="text"]:focus 是 (0,1,2,2);而 .search-input:focus 是 (0,0,2,0),前者赢。
立即学习“前端免费学习笔记(深入)”;
注意::is() 和 :where() 不叠加权重,只取内部最高项;!important 不参与这个计算,它是另一套“强制插队”机制。
为什么改了 class 还不生效?常见权重陷阱
你以为加了类就稳了,但可能早被更具体的选择器锁死:
- 写了
.btn-primary,但框架里有button.btn.btn-primary(权重(0,0,3,1)vs(0,0,1,0))→ 直接输 - 用了
div .title,但组件用了 scoped style 或 CSS Modules,真实 DOM 是div[data-v-abc123] .title[data-v-abc123]→ 你的选择器根本没命中 - 把自定义
<style></style>放在<link rel="stylesheet" href="bootstrap.css">前面 → 即使权重一样,也会被后加载的覆盖
解决方向很明确:要么提升你自己的选择器权重(加类、加父容器、用属性选择器如 button[data-type="submit"]),要么确保它在 HTML 中加载得更靠后。
Vue / React 项目里特别容易栽跟头的地方
框架的样式隔离机制会让“看起来一样”的选择器实际完全不匹配:
- Vue 的
<style scoped>会自动给所有选择器加属性哈希,.card .title实际编译成.card[data-v-xyz] .title[data-v-xyz] - React 的 CSS Modules 也是同理,
import styles from './Button.module.css'后,styles.btn是个唯一字符串 - Tailwind 的 utility 类冲突不是 class 写错顺序的问题,而是构建后 CSS 规则在文件里的声明顺序被破坏了(比如
@tailwind utilities被挪动或 HMR 缓存未清)
这类问题不能靠肉眼 debug,必须打开 DevTools 看 Styles 面板里真正生效的规则路径——它往往指向 component.abc123.css 或 tailwind.456789.css,而不是你本地编辑的文件。


















