sass用@use可天然隔离样式作用域,避免命名冲突;%placeholder比@mixin更优因按需生成css且不污染全局;@forward精准控制模块暴露成员;sass模块与css modules需协同,分别解决编译时和运行时作用域问题。

如何用Sass的@use隔离样式作用域
直接结论:Sass 从 1.23.0 开始废弃 @import,改用 @use 是解决命名冲突最有效、最轻量的方式——它天然创建私有命名空间,不会把变量、混合宏、函数全局暴露。
常见错误是仍沿用旧写法:@import "button",结果 $primary-color 在多个模块里被重复定义,最终以最后加载的为准,污染不可控。
-
@use后所有成员默认私有,必须显式通过as *或as btn才能访问,比如btn.$size-large - 一个模块只应
@use一次,多次@use不会重复执行,也不会合并命名空间 - 如果依赖第三方库(如
sass:map),也建议统一@use "sass:map"而非@import,避免与项目内同名函数冲突
为什么%placeholder比@mixin更适合基础样式复用
因为占位符选择器(%reset)在编译时只在实际 @extend 它的地方生成 CSS,而 @mixin 每次调用都会复制整段样式——这不仅放大命名风险(比如 @include reset 里写了 .icon,多个地方调用就可能意外覆盖全局 .icon),还会让 CSS 体积失控。
典型场景:重置类、工具类(%sr-only、%clearfix)、原子级样式基底。
-
%占位符不能单独出现在 CSS 输出中,必须被@extend,所以不会“意外泄漏”成真实选择器 -
@extend支持跨文件继承,但要求被继承的%必须已@use或@forward进当前作用域 - 不要对动态生成的选择器(如
.u-mt-#{$n})用%,它不支持插值,会报错"%placeholder" is not a valid selector
@forward怎么控制哪些成员对外可见
当你封装一个 UI 模块(如 _card.scss),又想把其中部分变量、混合宏透出给使用者,@forward 是唯一可控方式——它不像 @use 那样全量私有,也不像旧 @import 那样全量公开。
错误做法是把所有东西都塞进一个入口文件再 @import,结果下游项目一用就撞上 $border-radius、card-shadow() 等重名项。
- 用
@forward "card" show $size-medium, @mixin card-hover只暴露指定成员,其余自动隐藏 - 用
@forward "card" hide $private-token更适合内部常量过滤 - 如果转发时加了
as card-,那么下游必须写card-$size-medium,彻底切断命名耦合
为什么css-modules和Sass模块系统要配合用,而不是二选一
因为 Sass 的模块化管的是「编译时命名」,CSS Modules 管的是「运行时类名」;前者防开发阶段冲突,后者防打包后 DOM 渲染冲突——缺一不可。
比如你在 Button.module.scss 里写了 @use "theme" as t,Sass 确保 t.$color-primary 不会和别处的 $color-primary 混;但按钮最终生成的类名仍是 Button_button__abc123,靠 CSS Modules 保证它不会和另一个 button 类打架。
- 纯 Sass 模块无法防止不同组件里都写
.btn { color: red },最终 CSS 还是会层叠覆盖 - 只用 CSS Modules 而不用 Sass 模块,变量、断点、颜色体系依然散落在各文件,维护成本高,且容易出现
$spacing-xs在 A 文件是4px、B 文件是6px - Webpack 中需同时启用
css-loader?modules和sass-loader,且确保sass-loader版本 ≥ 12,否则@use语法解析失败
真正麻烦的不是语法,而是团队对「哪些该抽象成变量、哪些该收进 @forward、哪些该交给 CSS Modules 做局部作用域」缺乏共识——一旦有人绕过规范直接 @import 或硬写全局类名,整个隔离体系就失效了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











