当需复用带逻辑的声明(如计算、条件、前缀或参数化样式)而非单纯可变值时,应选@mixin;CSS变量仅适用于运行时可变的颜色、间距等值。

什么时候该用 @mixin 而不是 CSS 自定义属性?
当你要复用的是一组带逻辑的声明(比如带计算、条件、多浏览器前缀或参数化样式),而不是单纯可变的值时,@mixin 才是正确选择。CSS 自定义属性适合控制颜色、间距等运行时可变的值;@mixin 适合封装“生成样式”的行为——比如一个带 border-radius 和阴影的按钮基础样式,或者根据断点生成响应式栅格类。
如何定义带参数和默认值的 mixin?
参数让 @mixin 真正可复用。必须显式声明参数名,支持默认值(用 : 赋值),但不支持重载或可选参数列表。
@mixin flex-center($direction: row) {
display: flex;
justify-content: center;
align-items: center;
flex-direction: $direction;
}
调用时:@include flex-center(column) 或直接 @include flex-center() 使用默认值。注意:Sass 不校验参数类型,传错类型(比如传字符串给期望数字的参数)可能在编译时报错或产出无效 CSS。
@include 时为什么有时没生效?常见陷阱有哪些?
最常踩的坑有三个:
立即学习“前端免费学习笔记(深入)”;
- 在嵌套规则中
@include,但 mixin 内部用了&选择器,结果生成了意外的嵌套结构(比如.btn &__icon变成.btn .btn__icon); - mixins 定义在局部作用域(如某个嵌套块内),外部无法调用;
- 忘记在
@mixin中写实际声明——空 mixin 编译不出任何 CSS,也不会报错,容易误以为“调用了但没效果”。
另一个隐形问题:mixins 会原样展开,重复使用会导致 CSS 体积膨胀。比如在 20 个组件里都 @include responsive-text(),最终 CSS 就会复制 20 份相同的媒体查询块,而不是共享一份规则。
能否在 mixin 中用 @if 或循环动态生成样式?
可以,而且这是 @mixin 的核心优势之一。它支持完整的 Sass 脚本能力,比如按颜色 map 生成主题类:
@mixin generate-theme-classes($themes) {
@each $name, $color in $themes {
.theme-#{$name} {
--primary-color: #{$color};
color: #{$color};
}
}
}
@include generate-theme-classes((
light: #fff,
dark: #1a1a1a
));
但要注意:这类逻辑会让编译时间变长,尤其在大项目中遍历深层 map 或大量循环时。如果只是切换变量值,优先用 CSS 自定义属性 + JS 控制;只有当样式结构本身需要变化(比如不同主题下布局方向不同),才值得用 mixin 动态生成。
真正难的是权衡——把逻辑塞进 mixin 看似灵活,但调试时你看到的只是展开后的 CSS,原始 mixin 定义和调用点可能相隔很远。维护者得来回跳转才能理解一段样式的来龙去脉。


















