scss自定义函数必须用@function声明并包含@return语句,用于编译时数值计算;@mixin仅复用样式块,不返回值。字号函数应处理单位换算与缩放,避免在函数中写@media或@if判断设备,断点逻辑交由css规则处理。

SCSS自定义函数必须用@function声明,不能用@mixin
很多人误以为@mixin能返回值,其实它只做样式块复用,不支持计算后返回数值。字号这类需要参与运算的值,必须用@function——它会在编译时求值并内联为纯CSS数字。
典型错误是写成:@mixin font-size($n) { font-size: #{$n}rem; },这无法用于calc()或与其他数值相加,因为没返回值。
-
@function必须包含@return语句,且返回值类型要和调用上下文兼容(比如字号通常返回number) - 函数名建议用
font-size-*前缀,避免和未来CSS原生函数冲突 - SCSS函数不能访问DOM或运行时数据,所有输入必须是编译期已知的变量、数字、颜色等
基础字号函数:支持rem单位换算与断点缩放
实际项目中,字号往往需适配设计稿基准(如16px=1rem)并响应不同屏幕宽度。下面这个font-size()函数同时处理两件事:单位换算 + 基于em的相对缩放。
@function font-size($px, $base: 16px, $scale: 1) {
$rem: $px / $base;
@return $rem * $scale * 1rem;
}
使用示例:font-size(24px) → 1.5rem;font-size(24px, $scale: 0.9) → 1.35rem。注意$scale是无单位乘数,不是em值,避免重复单位报错。
- 别直接除
16(无单位),要用16px保持单位一致性,否则SCSS会报Incompatible units - 如果项目用
vw做流体字号,把@return改成$px / 375 * 100vw(假设设计稿宽375px) - 函数内不建议做
@if分支判断设备,那属于媒体查询职责,函数应保持纯计算
带断点的动态字号:用map-get查表比@if链更易维护
当字号需按断点阶梯变化(如手机14px、平板16px、桌面18px),硬写一堆@if嵌套难调试。更稳妥的方式是用map存配置,函数只负责查表和插值。
$font-sizes: (
sm: 14px,
md: 16px,
lg: 18px
);
<p>@function fluid-font-size($breakpoint) {
$px: map-get($font-sizes, $breakpoint);
@if not $px {
@warn "Unknown breakpoint <code>#{$breakpoint}</code> in $font-sizes";
@return 16px;
}
@return $px / 16px * 1rem;
}</p>
调用:font-size: fluid-font-size(md); → 1rem。关键点在于map-get失败时用@warn提示而非静默崩溃,方便定位拼写错误。
- 断点名(
sm/md)必须和$font-sizes键完全一致,区分大小写 - 不要在函数里写
@media,响应式逻辑应交给CSS规则本身,函数只输出当前断点对应的静态值 - 若需平滑过渡(非阶梯),改用
calc()生成表达式,但SCSS函数无法返回字符串"calc(...)",得用@mixin配合
函数返回值被calc()拒绝?检查单位是否混用
常见报错Invalid CSS after "...": expected expression,多因函数返回了带单位的值(如1.5rem),又被塞进calc(1rem + font-size(24px))——SCSS不允许在calc()内部调用函数,且calc()要求所有操作数单位可加减。
- 正确做法:函数只返回纯数字(如
1.5),CSS中写calc(#{$value}rem + 1rem) - 或彻底放弃
calc(),用SCSS原生运算:font-size: font-size(24px) + 1rem; - 若必须动态生成
calc()字符串,用@mixin拼接:@mixin calc-font($a, $b) { font-size: calc(#{$a} + #{$b}); },但失去类型校验
最常被忽略的是:SCSS函数在@keyframes或@container中同样不可用,这些上下文不支持函数调用,得提前计算好值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











