@extend 合并选择器不复制样式,%placeholder 是其安全模式;@mixin 每次调用都复制声明,支持参数、嵌套和 @content;选型取决于是否需要动态能力。

@extend 会合并选择器,不是复制样式
它把所有继承同一基类的选择器“塞进一条 CSS 规则里”,比如 .btn-primary 和 .btn-secondary 同时 @extend .btn,编译后变成:.btn, .btn-primary, .btn-secondary { color: #007bff; padding: 8px 16px; }。
常见错误现象:
- 基类
.btn被输出到最终 CSS 中,哪怕 HTML 里根本没用这个 class - 跨文件使用时,如果
@import顺序错乱,@extend会报错 “%btn is not a valid selector” - 嵌套中用
@extend(如&.active { @extend .btn; })会生成冗长选择器:.card .btn, .card .btn-primary
关键限制:不能传参、不能写条件逻辑、不支持 @content 插槽。它只认已存在的选择器,且必须在继承语句之前定义。
@mixin 是文本插入,每次调用都复制整块声明
@mixin 的行为像「粘贴」——@include btn-base 出现几次,对应样式就原样复制几次。没有选择器合并,也没有隐式依赖关系。
典型场景:
- 需要传入
$color、$size等参数时,只能用@mixin - 要嵌套
&:hover、@media或@content时,@mixin是唯一选择 - 调试友好:DevTools 里每个类都能直接跳转到对应的
@include行
体积风险:gzip 对结构化重复压缩效果有限,尤其当 mixin 包含嵌套规则时,重复声明明显。
%placeholder 是 @extend 的安全模式
%button-base 这种以 % 开头的占位符,本身不会输出任何 CSS,只在被 @extend 时才参与选择器合并。它解决了 @extend .btn 导致基类泄露的问题。
但要注意:
- 它和
@extend的行为完全一致——仍是静态合并,不支持参数或条件分支 - 仍受作用域限制:
%reset必须在@extend %reset之前@use或@import - 无法规避选择器爆炸:如果
%layout-center内部用了.grid .col-6这类复合选择器,继承后照样展开拼接
运行 sass --watch --style expanded 查看真实编译结果,是确认是否膨胀的最直接方式。
选哪个?看是否需要动态能力
如果样式块要传参、要响应主题切换、要包裹子内容,@mixin 是唯一可行路径;如果只是多个类共享完全一致的声明,且基类不打算在 HTML 中直接使用,%placeholder + @extend 生成的 CSS 最紧凑。
容易被忽略的一点:@extend 不改变选择器权重。你 @extend .btn,得到的 .btn-primary 依然只有单类权重,覆盖不了 #header .btn 这种高优先级规则——这时候硬加一个 .btn 类名到 HTML 才是实际解法,而不是指望 @extend 提升权重。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











