应使用命名空间和前缀隔离样式作用域:为根容器添加高辨识度class(如my-app),所有自定义CSS规则以此为前缀;手写class统一加项目前缀(如acme-button);避免通配符、!important和依赖加载顺序。

button、.container、[type="text"] 这类选择器没有作用域限制。你写的 .btn { color: red; } 很可能被框架里更具体的选择器(比如 .btn.btn-primary:hover)或后来加载的规则覆盖——不是“谁写在后面谁赢”,而是看**层叠顺序(cascade)、特异性(specificity)和加载顺序**三者共同作用。
常见现象包括:margin 被重置、font-size 突然变小、自定义 input 样式失效、伪类状态(:focus)不触发。
class="my-app" 或 class="legacy-ui"
.my-app button { ... }、.my-app .card-header { ... }
.my-app * { box-sizing: border-box; }),它们容易意外干扰框架组件内部结构.my-app {
--primary: #2563eb;
}
.my-app button {
background-color: var(--primary);
border: none;
}
.my-app .form-input {
padding: 0.5rem;
border: 1px solid #d1d5db;
}row、col、text-center),你的 .row 极可能被 Bootstrap 的 .row 覆盖。解决方案是强制前缀:
acme-(取公司/项目名缩写),而非 my- 或 custom-(太泛)acme-button、acme-card、acme-input-group
.acme-button { ... },不写 .button
prefixer 插件自动补全,但手动维护时前缀必须肉眼可见、不可省略!important 是临时止痛药,不是解法
把自定义 CSS 放在框架 CSS 之后,看似能“赢过”特异性,但实际风险很高:
.btn 升级为 .btn.btn-sm:focus-visible),你的样式立刻失效!important 会破坏可维护性,后续调试时无法靠浏览器 DevTools 的“划掉线”直观判断优先级!important,需显式开启,且开启后所有 utility class 都带 !important,反而加剧混乱真正要控制的,是作用域边界——命名空间和前缀不是“多此一举”,是在多人协作、长期迭代中守住样式控制权的最小成本手段。漏掉任意一层,后期排查 为什么这个 padding 就是去不掉 就得翻三遍框架源码。