根本原因是css加载顺序错误或选择器权重不足:需确保自定义css在bootstrap之后加载,并用.btn.my-btn等组合选择器提升权重至0,0,2,0,避免单独使用低权重类或!important。

根本原因不是你写错了,而是你的规则没赢过 Bootstrap 的 CSS——要么加载太早,要么选择器太弱,要么被 !important 或 CSS 变量绕开了。
检查 HTML 中 CSS 加载顺序是否真的正确
浏览器按 <link> 标签顺序解析样式,后加载的才有机会覆盖前一个。但很多人只看代码顺序,没确认实际网络请求是否成功。
- 打开 DevTools → Network 面板,刷新页面,确认
bootstrap.min.css(或bootstrap.css)在你的custom.css之前加载,且状态码是200 - Django/Flask 等框架中,
{% static 'css/custom.css' %}路径必须真实存在,否则文件根本没加载,连权重比拼的机会都没有 - Webpack/Vite 项目里,如果用
@import引入 Bootstrap,你的自定义样式也得写在它后面;用import时则依赖模块解析顺序,不如显式<link>可控
你的选择器权重压不过 .btn.btn-primary
Bootstrap 5 大量使用复合类名(如 .btn.btn-primary),特异性值是 0,2,0,0。而你写 .my-btn 只有 0,1,0,0,天然输一截。
- 别单独写
.my-btn { background: red; }——它不继承.btn的padding、border-radius,按钮会“变样”而不是“换色” - 正确做法是复用结构:
.btn.btn-primary.my-submit,既拉高权重,又保留所有基础样式 - 属性选择器更稳:
button[type="submit"].btn比单纯.btn更难被 DOM 变动影响 - 避免
#header .nav .btn这类深度嵌套——改个 class 名或删个 wrapper 就全失效
别忽略 :root 变量和工具类的“隐身覆盖”
Bootstrap 5.3+ 把很多样式逻辑转到了 CSS 自定义属性上,比如 text-transform 实际由 --bs-btn-text-transform 控制。你改 .btn-primary 的属性,可能根本没触达源头。
- 想全局改主色?优先在
:root里重设--bs-primary,而不是硬写.btn-primary { background: #xxx; } - 工具类如
.text-center、.d-none权重极低,但它们内部可能带!important;用.my-section .text-center就能轻松覆盖 - 拼错变量名(比如写成
--primary而非--bs-primary)或漏分号,整行会被浏览器静默忽略,DevTools 的 Computed 面板里根本看不到
DevTools 里真正该看什么
别只盯着 Elements 面板里你写的那行 CSS 是否显示出来——关键要看 Computed 面板里那个属性最终被谁决定。
- 右键元素 → “检查”,在右侧面板点开目标属性(比如
color),灰色划掉的值就是被覆盖的,蓝色加粗的是胜出者 - 如果胜出者是
bootstrap.min.css,说明顺序或权重不够;如果是内联样式或 JS 注入的 style,就得查 JS 逻辑 - 注意
* { box-sizing: border-box }这种通配规则——它连子元素都管,想局部改得用.my-wrapper * { box-sizing: content-box }
最常被跳过的其实是缓存问题:CSS 文件明明改了,但浏览器加载的还是旧版,连 DevTools 的 Sources 里看到的都不是最新代码。清缓存不是备用方案,是排查第一步。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











