函数返回可参与calc()运算的数值,混合宏仅输出固定样式块;函数编译期求值复用、支持类型检查与嵌套逻辑,混合宏则重复插入、无类型约束且不可被引用。

函数返回值能直接参与 calc() 和单位运算,混合宏不能
混合宏本质是样式块的文本插入,它输出的是完整声明(比如 width: 12px),无法被其他表达式引用或计算。而函数返回的是纯数值(带单位或不带),可直接用在 calc()、min()、属性值计算中。
-
@function px-to-rem($px) { @return $px / 16px; }→ 可用于font-size: #{px-to-rem(24)}rem; - 若写成
@mixin px-to-rem($px) { font-size: #{$px / 16px}rem; },就只能生成固定声明,没法传给margin-inline: calc(#{px-to-rem(8)}rem + 1ch); - 函数返回值还能参与条件判断:
@if px-to-rem(16) > 1 { ... };混合宏里做@if判断只能影响自身输出,不能作为“值”被外部使用
混合宏重复调用会膨胀 CSS,函数只计算一次
每次 @include 都把整个样式块复制一遍,哪怕参数相同;而函数调用在编译期求值,结果复用——尤其在生成栅格系统、间距阶梯这类大量数值场景下,差异明显。
- 写
@mixin spacing($step) { margin: #{$step * 4}px; },在 20 个地方调用@include spacing(2),编译后就是 20 条重复的margin: 8px; - 改用
@function spacing($step) { @return $step * 4px; },配合margin: spacing(2);,编译器识别出相同输入,通常只计算一次(Dart Sass 优化行为) - 更关键的是:函数可用于生成变量值,比如
$space-md: spacing(3);,后续所有用到$space-md的地方都共享同一数值,不会重复计算
函数支持类型检查和错误提示,混合宏做不到
混合宏对参数类型完全宽容,传错单位、传字符串当数字,往往静默编译成功但输出无效 CSS;函数可用 @error 主动拦截并报错,提前暴露问题。
@function clamp-min($val, $min) { @if type-of($val) != 'number' { @error 'clamp-min: $val must be a number'; } @return max($val, $min); }- 若误传
clamp-min('12px', 8px),立刻中断编译并提示,而不是生成max('12px', 8px)这种非法 CSS - 混合宏里放
@if type-of($val) != 'number'只能控制是否输出某段样式,无法阻止错误参数进入,也无法阻止无效 CSS 生成
函数能嵌套调用并组合逻辑,混合宏只能线性展开
函数可以互相调用、链式计算,适合构建数值工具链;混合宏是扁平的样式注入,嵌套调用只是把多个块拼在一起,无法形成“值流”。
-
@function em($px) { @return $px / 16px; } @function fluid($min, $max) { @return clamp(em($min), 1vw, em($max)); }→ 可用于font-size: fluid(16px, 24px); - 试图用混合宏模拟:
@mixin fluid($min, $max) { font-size: clamp(#{em($min)}rem, 1vw, #{em($max)}rem); }看似可行,但em()必须是函数——混合宏内部不能定义/调用函数,只能调用已有函数 - 真正复杂的数值逻辑(如基于黄金比例生成字号阶梯、根据断点计算缩放因子)必须靠函数组织,混合宏只负责“把算好的数塞进 CSS 声明”
函数不是万能的,但它处理数值这件事本身就有不可替代性。混合宏管“怎么写样式”,函数管“写什么数值”——混淆这两层,容易在主题系统、设计令牌、响应式计算中陷入维护泥潭。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











