不推荐用 @for 生成间距类,因其产生冗余 CSS、不支持负值与单位变更,且语义断裂;健壮方案是用 @each 遍历带单位的 map。

直接用 @for 生成间距类是可行的,但容易产出大量无用 CSS、无法支持负值、语义断裂,**不推荐作为主力方案**;真正健壮的做法仍是 @each 遍历带单位的 map。
为什么 @for $i from 1 through 24 会出问题
常见错误现象:.m-123 类被生成但从未使用,CSS 体积膨胀 30%+;.m-n2(负边距)完全无法表达;修改基础单位(如从 0.25rem 改为 4px)需重写全部循环逻辑。
根本原因在于:@for 只能处理纯数字序列,无法绑定语义键名(如 "sm"、"lg"),也不能天然区分正负、单位、方向组合。
- 数值型键名(如
1,2)可省引号,但和语义命名混用时极易混乱 - 若想支持负值,得额外加一层
@if $i 判断,但 <code>@for不支持负向递增,只能拆成两个循环 - 单位必须手动拼接:
#{$i}px→ 一旦项目切到rem,所有@for循环全要改
@for 仅适合极简、固定像素场景
如果你明确只要 px 单位、只覆盖 0–40 像素、且无需响应式或负值,@for 确实快:
立即学习“前端免费学习笔记(深入)”;
@for $i from 0 through 40 {
.mt-#{$i} { margin-top: #{$i}px; }
.mb-#{$i} { margin-bottom: #{$i}px; }
}
但注意:
- 起始值用
0而非1,否则漏掉零值重置类 - 必须用
through,to 41写法易错且语义不清 - 不要试图在同一个
@for里塞进margin/padding/left/right—— 组合爆炸会让编译慢、CSS 膨胀、调试困难
@each + map 才是可维护的正解
真正解决“批量 + 语义 + 单位 + 负值”的唯一方式,是用 map 显式定义键值对:
$spacers: (
"0": 0,
"1": 0.25rem,
"2": 0.5rem,
"3": 1rem,
"n2": -0.5rem
);
@each $key, $val in $spacers {
.m-#{$key} { margin: $val; }
.mt-#{$key} { margin-top: $val; }
}
关键约束:
- 所有键名必须加引号:
"n2"✅,n2❌(否则 Sass 报Undefined variable "n2") - 值必须带单位:
0.5rem✅,0.5❌(否则参与计算时报Invalid null operation) - 负值直接作为 map 的一个合法键值,无需额外逻辑
别让 @for 掩盖设计缺陷
用 @for 生成一堆 .m-1 到 .m-99,本质上是在把设计系统缺失的问题,转嫁给 CSS 编译器。真实项目中,你需要的是 .m-sm、.m-lg 这类能被设计师理解、前端复用、产品评审的语义化标记 —— 这些只能靠 map 定义,没法靠数数生成。
最容易被忽略的一点:当你在 @for 循环里写 #{$i}rem 时,Sass 并不会检查这个 $i 是否真对应设计规范里的某个层级;而 map 的键名本身就是设计约定的快照,改一个键就等于改一次设计决策。


















