占位符选择器 % 仅在被 @extend 调用时输出样式,且须满足定义扁平、无上下文、跨文件显式 @use 三条件才减体积;否则因无法合并而重复输出,导致 css 更大。

占位符选择器 % 本身不输出任何 CSS,只有被 @extend 调用时才把样式合并进目标选择器——这是它能真正减体积的唯一前提。用错地方(比如嵌套里 @extend、跨媒体查询引用、或继承含伪类的占位符),编译后 CSS 体积反而更大。
为什么 @extend %placeholder 有时让 CSS 更大?
SCSS 不做语义判断,只机械拼接选择器。一旦触发“无法安全合并”,就会退化为重复输出:
-
.card__title和.list__item都@extend %text-emphasis,但若%text-emphasis定义在.theme-dark块内,Sass 会生成两套独立规则,而非合并 - 出现
&:hover、@media、.parent &等上下文,%就失去“静默”属性,编译后可能产出.card__title:hover、.list__item:hover两条规则 - 复合选择器定义占位符,例如
.utility %text-center,被@extend后会生成.btn .utility .text-center这类冗余路径
哪些 % 是安全的?三个硬条件必须同时满足
只有同时守住这三条,% 才能发挥去重作用:
- 定义必须扁平:
%sr-only可以,.a .b %sr-only不行 - 内容必须无上下文:
%truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }安全;%btn-hover { &:hover { color: blue; } }危险 - 跨文件使用必须显式
@use:@use "shared/placeholders" as *;,然后@extend placeholders.%sr-only;不能靠@import隐式暴露
什么时候该立刻放弃 %,改用 @mixin?
% 无法传参、无法响应状态、无法嵌套逻辑——这些不是限制,而是信号:你本就不该用 @extend。
- 需要圆角差异化:
@mixin rounded($radius: 4px),而不是写死%rounded-sm和%rounded-lg - 要支持暗色主题切换:
@mixin text-color($mode: light)内部用if分支,%做不到 - BEM 组件复用:
.card__title和.modal__title共享字体加粗逻辑,用@include text-emphasis,别用@extend %text-emphasis——否则 PurgeCSS 无法识别未用类
最常被忽略的一点:% 的价值不在“写得少”,而在“删得准”。一旦它和 @media、伪类、嵌套结构耦合,你就主动放弃了构建时压缩和运行时匹配效率的双重保障。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











