应优先选@mixin,因其支持参数、条件逻辑和@content;无动态需求且基类不被html直接使用时,@extend或%placeholder才适用。

Mixin每次@include都复制整套规则
编译时,@mixin 就像一个“粘贴指令”:你调用一次 @include button-base,Sass 就把整个 @mixin button-base 里的声明原样复制进去。调用 10 次,就生成 10 份几乎相同的 CSS 块——哪怕只有 color 和 padding 两行,也会重复 10 遍。
常见错误现象:.btn-primary、.btn-secondary、.btn-danger 全部用同一个带参数的 @mixin btn-variant 生成,结果编译后出现大量重复的 border: 1px solid ...、background-color: ...、&:hover { ... } 块。
- 体积影响明显:gzip 对这类结构化重复压缩有限,尤其当 mixin 包含嵌套规则(如
&:hover、@media)时 - 调试友好:DevTools 里每个按钮类都有独立样式来源,点击就能跳转到对应
@include行 - 不支持跨文件复用参数逻辑:你不能在另一个文件里
@extend一个带$size参数的抽象基类——@extend只认已存在的选择器,不认变量
@extend合并选择器但保留所有被继承的选择器
@extend 不复制声明,而是把多个选择器“塞进同一组 CSS 规则里”。比如 .btn-primary { @extend .button-base; } 和 .btn-secondary { @extend .button-base; },编译后变成:.button-base, .btn-primary, .btn-secondary { color: #007bff; padding: 8px 16px; }
问题在于:.button-base 这个类只要在 Sass 中定义过(哪怕没在 HTML 里用),就会出现在最终 CSS 里。它不是“占位符”,而是实打实输出的选择器。
- 表面体积小,但存在冗余风险:如果
.button-base后来被删掉,而某处@extend .button-base没同步清理,编译仍通过,CSS 里却留下无意义的.button-base选择器 - 作用域失控:一旦 HTML 中意外出现
class="button-base",整组规则立刻生效,可能覆盖其他样式 - 无法响应状态变化:你不能写
@extend .button-base if $theme == 'dark'——@extend是静态的,没有条件分支能力
占位符 %placeholder 看似安全实则难调试
%button-base 是 @extend 的“隐身版”:它只在被 @extend 时才输出 CSS,避免了基类泄露。但它的行为和 @extend 完全一致——仍是选择器合并,仍是静态继承。
真正麻烦的是调试:%button-base 在 DevTools 里完全不可见,你看到的只是合并后的选择器列表,根本不知道哪条样式来自哪个占位符。遇到样式冲突时,得翻遍所有 @extend %... 才能定位源头。
- 它解决不了动态需求:依然不能传参、不能
@content、不能@if - 和
@mixin混用会放大问题:比如在@mixin内部@extend %base,Sass 会先展开 mixin(复制 N 份),再对每一份分别做 extend(合并),极易引发选择器爆炸 - 团队协作时容易误用:新人看到
%就以为“更轻量更安全”,结果写出一堆无法追踪的继承链
选 mixin 还是 extend,关键看是否需要参数或条件逻辑
别纠结“哪个更优雅”,直接看代码里有没有 $ 开头的变量、@if、@for 或 @content。有,就必须用 @mixin;没有,且基类稳定、不会被 HTML 直接使用,@extend 或 %placeholder 才值得考虑。
- 按钮尺寸适配:
@mixin btn-size($s)内部用@if $s == sm { padding: 4px 8px; }——@extend做不到 - 主题色切换:
@mixin theme-color($color)动态设置background和border——@extend只能写死一套 - 纯视觉复用(如统一圆角、阴影):若所有地方都用固定值,且基类绝不会出现在 HTML 中,
%rounded+@extend %rounded是合理选择
最常被忽略的点:Mixin 的体积代价是明确的、可预测的;Extend 的维护代价是隐性的、爆发式的——它不报错,但会让 CSS 输出越来越难理清来源。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











