不能直接用 px 写死尺寸,因其破坏响应式与主题切换;应以 1rem 为基准,用 Sass 函数显式表达比例关系,并通过类型判断、map 管理多档尺寸,避免 CSS 膨胀。

为什么不能直接用 px 写死尺寸?
写死 px 值会让响应式和主题切换变得极其脆弱。比如一个按钮高 40px,在高DPI屏或缩放 125% 时可能显得过小;换深色主题时若需同比例放大所有控件,就得全局搜替换——这根本不可维护。
Sass 的函数(如 rem()、scale()、自定义 size())本质是编译期计算,它把设计系统中的「基准」和「比例关系」显式表达出来,而不是靠人脑心算。
- 推荐以
1rem == 16px为根字号基准(即html { font-size: 16px; }),所有尺寸基于此推导 - 避免在函数里硬编码
16,改用1rem或16px作为参考单位,让函数可读性更强 - 别在
@media查询里重复调用同一函数生成不同值——应提前定义断点变量,再传入函数
size() 函数怎么写才不踩坑?
很多人写 @function size($n) { @return $n * 4px; },看似简洁,但会出问题:当传入 size(2em) 时,2em * 4px 是非法运算,Sass 报错 Incompatible units: 'em' and 'px'。
真正健壮的 size() 应只接受无单位数字或明确单位,并做类型判断:
立即学习“前端免费学习笔记(深入)”;
@function size($n) {
@if type-of($n) == 'number' and unit($n) == '' {
@return $n * 1rem;
} @else if unit($n) == 'px' {
@return $n / 16 * 1rem;
} @else {
@return $n;
}
}-
size(2)→2rem(最常用,对应 32px) -
size(32px)→2rem(兼容旧项目迁移) -
size(1.5em)→ 直接返回1.5em(不强行转 rem,保留语义) - 不要试图支持
size(2vh)这类动态单位——它们本就不该进尺寸函数
如何用 map-get() 管理多套尺寸体系?
产品有「紧凑模式」「标准」「宽松」三档时,硬写三套 size-sm()/size-md()/size-lg() 函数太冗余。用 map + map-get() 更干净:
$sizes: (
sm: (1: 0.5rem, 2: 0.75rem, 3: 1rem),
md: (1: 0.75rem, 2: 1rem, 3: 1.25rem),
lg: (1: 1rem, 2: 1.25rem, 3: 1.5rem)
);
<p>@function size($level, $mode: md) {
@return map-get(map-get($sizes, $mode), $level);
}-
size(2, sm)返回0.75rem,size(2)默认用md档 - 修改某档尺寸只需改
$sizesmap,无需动函数逻辑 - 注意
map-get()查不到键时返回null,建议加@warn提示缺失 key
编译后 CSS 体积和性能要注意什么?
Sass 函数是编译时执行的,不会增加运行时开销,但容易无意中导致 CSS 膨胀。比如在循环里用 @for $i from 1 through 20 { .m-#{$i} { margin: size($i); } },会生成 20 行独立规则——而实际可能只需要 .m-1 到 .m-4。
- 优先用
size()计算关键组件尺寸(按钮、卡片、间距),别覆盖所有原子类 - 避免在
@each中对每个 map key 都生成完整样式块,先确认是否真需要全量输出 - 开启 Sass 的
--style compressed并检查 sourcemap,确认函数调用没残留未使用的中间变量
函数本身不难写,难的是想清楚哪些尺寸该抽象、哪些该保留原始语义。比如 border-radius 用 size(1) 就很怪,它更适合用 radius-sm/radius-lg 这类语义化变量——尺寸函数不是万能胶,它只解决「线性缩放」问题。


















