%占位符不输出CSS,仅配合@extend在扁平结构中生效,可合并选择器减少体积;跨文件需@use显式引入;无法传参、嵌套或用于媒体查询,此时应改用@mixin。

能显著减少重复CSS,但必须用对方式——%占位符本身不输出任何样式,只有配合@extend且满足扁平结构、正确引入、无嵌套定义时,才真正压缩体积。
为什么%reset-text比.reset-text更省体积
占位符以%开头,Sass 编译器默认不把它转成任何 CSS 规则;而普通类名哪怕没人用,也会原样出现在最终文件里。更关键的是:@extend %reset-text会让所有调用它的选择器合并成一条规则,比如.title, .subtitle, .caption { margin: 0; line-height: inherit; };但@extend .reset-text会保留.reset-text自身那条空规则,还可能把它的伪类(如.reset-text:hover)一并拖进来,造成冗余。
-
%reset-text只作为“骨架”存在,HTML 中完全不能写class="reset-text" - 多个选择器同时
@extend %reset-text,编译后只有一条声明,不会复制样式块 - 如果
.reset-text含&:hover,那么所有继承它的类都会生成各自的:hover变体,这通常不是你想要的
@extend %placeholder在嵌套结构里为何失效
@extend只作用于当前选择器本身,不会穿透嵌套层级。比如写成.card { @extend %bordered; &__header { color: red; } },只有.card获得%bordered样式,.card__header不会自动继承。
- 想让子元素也应用同一套基础样式?得单独写
.card__header { @extend %bordered; } -
&在嵌套中表示父选择器,但它不影响@extend的作用范围 - 不要指望
%base能自动覆盖.card .content p这类深层结构——它只认直接声明的选择器
跨文件使用%placeholder必须显式引入
Dart Sass v7.0+ 默认禁止隐式跨文件@extend。%占位符不会自动暴露到其他文件,必须通过@use显式导入,否则编译报错Extending unknown pseudo-class "%xxx"。
立即学习“前端免费学习笔记(深入)”;
- 推荐写法:
@use "base" as *;之后可直接@extend %reset-text - 若不用
as *,则必须写全名:@extend base.%reset-text - 禁止循环依赖:A 文件
@use "B",B 就不能再@use "A" - 报错
Warning: You're extending a selector that isn't defined时,先检查@use路径和顺序,别急着加!optional
哪些场景该放弃%,改用@mixin
%是纯静态复用,零灵活性;一旦需要传参、条件分支、包裹@media或动态计算值,它就无能为力。
- 按钮需根据
$variant参数生成不同背景色?用@mixin btn($variant),别硬套%btn-base - 要为移动端单独重置某组间距?
@mixin reset-spacing-mobile比%reset-spacing更可控 - 想在
@media (min-width: 768px)内覆盖某套基础样式?@mixin可直接嵌套媒体查询,%做不到
真正容易被忽略的是:占位符一旦定义在@media块内部,就会被锁死在那个作用域里,外部@extend必然失败——这个限制没有警告,只有静默报错。


















