CSS层叠规则中后加载样式覆盖前序样式属正常行为,关键在于通过控制<link>顺序、选择器权重及构建工具import顺序来确保目标样式生效,而非简单阻止覆盖。
后引入的 CSS 覆盖前面样式,通常不是异常,是 CSS 层叠(cascade)的正常行为——只要选择器权重相同,后加载的规则就赢。关键不在“阻止覆盖”,而在“控制谁该赢”。
别急着改代码,先用浏览器开发者工具验证:
<link>;如果来源是你写的 CSS 文件,但被后面某个库的 CSS 划掉了,就是顺序问题200,排除 404 导致“你以为加载了,其实没加载”Ctrl + F5 或 Cmd + Shift + R),并勾选 Disable cache
HTML 中 <link> 的物理顺序直接决定源顺序(source order),这是层叠规则的底层依据:
bootstrap.min.css、tailwind.css)必须放在最前面base.css、reset.css)紧随其后Button.module.css、home.css)放中间custom-theme.css、dark-mode.css)必须放在最后<link> 插入到 <head> 末尾——它天然晚于静态标签,极易意外覆盖Vite / Webpack 不会照搬 HTML 里的 <link> 顺序,而是按 JS 入口文件中的 import 语句顺序打包 CSS:
import 'bootstrap/dist/css/bootstrap.min.css' 出现在 import './custom.css' 之前@import 'bootstrap/scss/functions' 之前定义 $primary 等变量style 标签或 CSS-in-JS(如 styled-components)生成的样式默认插入 <head> 末尾,不受 HTML 顺序控制,需手动指定注入容器<style scoped> 不会匹配全局类(如 .btn),但如果你写 .btn { color: red; },它根本不会生效——因为框架的 .btn 不在该组件 DOM 上!important 是紧急兜底,不是设计手段。滥用会导致维护雪球:
:root { --bs-btn-color: #2c3e50; --bs-btn-bg: #3498db; }
.Button-root .btn 或 .btn.btn(权重从 0,1,0 → 0,2,0)div .btn 这种无意义标签提权,影响性能且不可读* { box-sizing: border-box; })会穿透进所有模块,改用 :where(*) { box-sizing: border-box; } 降权真正容易被忽略的点:即使你调对了 <link> 顺序,如果自定义 CSS 里用了比框架更低的选择器权重(比如只写 .btn,而框架用的是 .btn.btn-primary),照样被盖。覆盖不是靠“后”,而是靠“后且不弱”。