




直接用类名易致全局样式污染,因CSS按层叠规则生效且无文件作用域;BEM通过命名空间划分语义边界;属性选择器可隔离第三方样式;CSS Modules能彻底解决冲突但需构建支持;统一团队命名规范才是关键。
全局作用域下,CSS 类名一旦重复,后加载的样式就会覆盖先加载的。尤其在多人协作或集成第三方组件时,.btn、.header 这类通用名极易冲突。浏览器不关心你写在哪个文件里,只按层叠规则(cascade)和优先级(specificity)生效。
.active 可能同时被导航、标签页、模态框使用 !important 滥用会进一步破坏可维护性 BEM(Block–Element–Modifier)不是银弹,但能从命名上强制划分作用域。核心是让每个类名自带“归属感”,比如 user-cardavatar--large 明确属于 user-card 模块,不会和 product-listavatar 冲突。
container、wrap 这类泛化词 连接,Modifier 用双短横 --,不嵌套层级(如不用 user-cardheader__title) @include ns('user-card') { ... } postcs
s-bem 能自动补全或校验命名 当无法修改第三方库源码(如引入了 highlight.js 或 codemirror),靠层级太脆弱(.cm-editor .cm-line 一旦库升级就可能失效),更可靠的是加一层属性锚点:
data-scope="code-block",然后写 [data-scope="code-block"] .cm-line { ... } .my-app .cm-line)更轻量,不依赖父容器类名稳定 [class*="cm-"] 这类模糊匹配,易误伤 CSS Modules 在构建时自动哈希类名(Button_buttonF1a2b),彻底解决命名冲突,但需配套构建工具(Webpack/Vite),且动态 className 拼接要小心(styles[`${prefix}icon`])。
:is(.user-card, .product-card) .title 可减少重复书写,但注意 :is() 不影响 specificity 计算,别指望它提升优先级 真正难的不是选哪种方案,而是团队能否统一命名习惯、守住 scope 边界。一个没加命名空间的 .loading 类,可能让三周后的某个深夜排查变成一场灾难。