直接加.component-name仍被全局样式覆盖,因Sass嵌套不生成命名空间,编译后选择器仍平铺全局;需用唯一前缀(如.uikit-modal)配合&实现强隔离,并统一团队前缀规范。

为什么直接加 .component-name 还是被全局样式覆盖?
Sass 的嵌套本身不产生命名空间,@import 后所有选择器平铺进全局 CSS 作用域。哪怕你写了 .modal { .header { ... } },编译出来仍是 .modal .header,一旦项目里其他地方也定义了 .header,优先级或加载顺序不对就冲突。
- 真实场景:组件库和业务代码共用
button、input等基础类名,第三方 CSS(比如重置样式或 UI 框架)先加载,你的局部样式后加载但权重不够 - 关键点:CSS 优先级看选择器特异性(specificity),不是文件顺序;嵌套不等于隔离
- 常见错误现象:
!important滥用、反复调高选择器层级(如.a .b .c .d),最终导致难以维护和复用
用 class 命名空间比 BEM 更轻量的实践方式
不需要强制 BEM 的完整命名规范(如 block__element--modifier),只要在组件根元素上加唯一前缀,再让所有子选择器以该前缀为父级约束即可。Sass 的 & 能自然承接这个逻辑。
- 示例:
.uikit-modal { &__header { font-size: 1.2rem; } &__body { padding: 1rem; } &__footer { text-align: right; } }编译后生成的是.uikit-modal__header这类强隔离类名,不会和.dialog__header或纯.header冲突 - 注意
&必须紧贴选择器,写成& <strong>header</strong>(中间有空格)会失效,变成全局header - 前缀建议用项目/组件域名称(如
auth-、dash-),避免泛化词如my-或custom-,否则多人协作时仍可能重复
@use 替代 @import 后,变量和 mixin 不再全局污染
@import 是简单拼接,所有 $var、@mixin 全局可见;@use 则默认私有,必须显式通过 as * 或带前缀调用,天然形成模块边界。
- 正确写法:
@use 'base/variables' as base;
然后用base.$color-primary,不会和另一个variables文件里的$color-primary冲突 - 容易踩的坑:
- 旧项目混用
@import和@use,Sass 会报错,必须全量切换 -
@use只能出现在文件顶部,不能放在嵌套规则里 - 如果依赖第三方 Sass 库(如 Bootstrap),确认它已发布
module版本(即含index.scss且支持@use),否则仍得用@import
- 旧项目混用
伪类、响应式、状态类怎么安全嵌套进命名空间?
不要把 :hover、@media、&.is-open 写在最外层,而是作为 & 的延续,确保它们始终绑定在命名空间下。
立即学习“前端免费学习笔记(深入)”;
- 正确:
.card { &__title { color: #333; } &:hover &__title { color: #007bff; } @media (max-width: 768px) { &__content { font-size: 0.9rem; } } }编译后是.card:hover .card__title和@media (max-width: 768px) {.card__content {...}},完全受控 - 错误写法:
.card:hover { .card__title { ... } }—— 这样.card:hover是独立选择器,若页面其他地方也有.card,就会意外触发 - 性能提示:过度嵌套(超 4 层)会让 CSS 体积增大、浏览器匹配变慢,命名空间控制在 2–3 层内更稳妥
真正难的不是写对语法,而是团队对「谁负责定义前缀」「第三方组件如何接入命名空间」「设计系统 token 是否也走同一套 scope」达成一致。这些没对齐,再规范的 Sass 也会在联调时突然崩出一个 .btn 覆盖掉全部按钮。


















