CSS选择器优先级冲突源于局部与全局类名权重相同,浏览器按层叠顺序后加载者生效。CSSModules仅哈希命名空间,不改变权重。优化方式包括BEM命名自带语义、双重类名或父级限定提升权重,全局样式应收窄作用域,避免!important与ID选择器滥用。
在组件中精心编写样式后,页面渲染时仍被全局样式覆盖,这一问题并不少见。使用开发者工具检查发现,全局选择器由于排在后面,直接覆盖了本地样式。此时你可能会怀疑 CSS Modules 未生效,但实际原因往往更简单——选择器权重不足。

长期稳定更新的攒劲资源: >>>点此立即查看<<<
问题的核心并非“CSS Modules 未生效”,而是局部类名(如 .btn_abc123)与全局类名(如 .btn)的权重相同,两者都属于「类选择器」。浏览器按照层叠顺序处理,排在后面的规则胜出。Vite 的 CSS Modules 仅对类名进行哈希处理,并不改变权重——.btn 和 .btn_abc123 的权重均为 c=1,谁写在后面谁就生效。
常见错误场景:Button.module.css 中定义了 .btn { color: red; },但页面按钮仍显示蓝色;通过开发者工具发现,全局 global.css 中的 .btn 规则位于后面,直接覆盖了组件样式。因此,不要期望 CSS Modules 能自动“隔离权重”,它只负责隔离命名空间。
.btn、.title 等类名,这是冲突的源头div.btn 这种组合在模块化环境中极不可靠BEM 并非为了多写几个下划线,而是让每个类名自带作用域语义,从设计上规避“靠嵌套赢”的陷阱。一个 .card__title--large 就是完整、独立、可预测的单元,无需借助 .card .title 这样的结构来争夺权重。
在 React/Vue 组件中,每个视觉元素都应拥有 Block 或 Element 级别的类名,且不能省略前缀:
,对应 CSS 中的 .article__heading,再添加 .article .heading——这又回到权重竞争的老路--disabled)仅用于表达状态,不应用于布局微调;布局调整应使用 --full-width 等语义明确的修饰符,而非 --disabled相比 !important,优先通过结构优化来提升权重。这样既不会污染全局,也不会破坏代码的可维护性。
.btn { &.btn { color: red; } } → 权重从 c=1 提升至 c=2,可稳定覆盖全局 .btn.my-button { .btn { color: red; } } → 实际生成 .my-button_abc .btn_def456,权重为 c=2.btn { &[class*="btn"] { background: blue; } } → 同样达到 c=2,且不依赖 DOM 结构层级注意:!important 应是最后手段。它只能掩盖问题,而非真正解决——下一次修改时可能需要两个 !important,或删除旧规则,但无人敢轻易操作。
全局样式并非不能使用,而是应当主动收窄作用域。与其与局部样式对抗,不如让它“根本匹配不到”。
.btn 改为 .global-btn 或 .legacy-btn,明确语义边界.theme-legacy .btn,确保只在添加了 theme-legacy 类的根节点下生效#app)——其权重过高(b=1),后续几乎只能靠 !important 或内联样式覆盖真正的难点并非计算权重,而是让每一条样式规则的意图清晰可见。当你看到 .user-card__avatar--small 时,就知道它只控制头像尺寸,不会顺手修改边框或颜色——这种克制,比任何 !important 都更有效。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述