根本原因是选择器权重不足、加载时机被绕过或CSS变量被静默覆盖;应通过DevTools「Computed」面板定位生效规则,用组合类提权、:where()降权、变量重定义或限定作用域解决。

自定义 CSS 被覆盖,不是因为你没写对,而是浏览器压根没选中你的规则——选择器权重不够、加载时机被绕过、或变量被静默劫持。
检查 Computed 面板里哪条规则真正生效
别只盯着 Elements 面板看 class 有没有加。右键目标元素 →「检查」→ 切到「Computed」→ 点开某个属性(比如 color 或 background-color):
- 如果来源是
bootstrap.min.css且值被划掉,说明你的规则根本没参与层叠计算(文件可能 404 或未加载) - 如果来源是你自己的文件但属性带删除线,说明权重输了:
.btn(0,0,1,0)打不过.btn.btn-primary(0,0,2,0) - 如果颜色变了但不对劲(比如 hover 不响应),可能是
--bs-primary这类变量在:root里被 Bootstrap 后设,你改.btn-primary { background: red }会被变量值顶掉
确保 custom.css 在 bootstrap.min.css 之后加载,且不被构建工具干扰
HTML 中的 <link> 顺序是硬性前提,但 Vite/Webpack 等工具可能打乱实际注入时机:
- ✅ 正确写法:
<link href="bootstrap.min.css"> <link href="custom.css"> - ❌ 错误写法:
<link href="custom.css"> <link href="bootstrap.min.css">(直接让 Bootstrap 覆盖你) - ⚠️ 构建工具陷阱:用
@import在 SCSS 里引入 custom.css,或用 JS 动态import('./custom.css'),都可能导致它在 DOM 中晚于 Bootstrap 注入 - ? 验证方式:Network 面板里确认
custom.css的「Initiator」列是否显示为 HTML,而不是某个 JS 文件
用组合类提权,而不是堆 !important
单写 .my-btn 永远赢不了 .btn.btn-primary:focus。要精准提权,同时保留 Bootstrap 基础样式:
立即学习“前端免费学习笔记(深入)”;
- 复用结构:
.btn.my-submit权重升到 0,0,2,0,和.btn.btn-primary平级,靠加载顺序决胜 - 限定作用域:
.dashboard .btn.my-submit升到 0,0,3,0,还能自然隔离不同区域的样式 - 避免 ID:
#header .nav .btn一改 DOM 就断,维护成本高 - 慎用
!important:Bootstrap 5 工具类(如.text-center)本身带!important,你加了反而可能被它反杀
JS 动态插入的节点(Modal/Tooltip)天然脱离你的样式作用域
Bootstrap 的 Modal、Tooltip 默认 append 到 document.body,完全跳出你写的 #app 或 .my-section 容器:
- 你在
#app .btn里写的样式,对 body 下的<div class="modal"> 无效 <li>兜底方案:给动态组件手动加 class,比如初始化 Modal 时传 <code>container: '.my-app',让它插入到你可控的父容器内 - 更稳做法:用属性选择器锚定,例如
button[data-ui="bootstrap"],再配合data-bs-toggle属性匹配,不受插入位置影响 - 现代方案:用
:where()降权隔离,:where(.my-app) .btn权重恒为 0,0,1,0,和原生.btn拉平,纯靠加载顺序控制
真正难调的从来不是“怎么写一行能生效的 CSS”,而是哪些地方会“意外穿透”:reboot.css 重置了 button 边框、[data-bs-toggle] 选择器权重高得离谱、Vite 注入 CSS 的时机和浏览器解析顺序不一致——这些细节不查 DevTools 的「Computed」和「Specificity」数值,光靠猜永远调不准。


















