直接用@each遍历map生成边距类更安全语义化;@for仅提供数字索引,无法映射语义名、易致单位拼接错误、难扩展负边距与响应式,且后续调整需重写逻辑。
直接用 @each 遍历 map 生成边距类,比 @for 更安全、更语义化;硬写数字范围或混用单位会埋下编译失败或运行时错位的坑。
@for $i from 1 through 12 直接循环这种写法看似简洁,但实际项目里很快会卡住:
@for 只给数字索引,拿不到语义名(比如你没法让 .m-3 对应 0.75rem 而不是 3px)#{$i}px 没问题,但换成 #{$i}rem 就变成字符串拼接,Sass 不报错但 CSS 生效不了.m-n2)或响应式断点(md:m-3),单层 @for 无法自然嵌套结构"2": 0.5rem 和 "4": 1.5rem),就得重写整个循环逻辑$spacers 必须是 map,且键值都要带约束正确结构长这样:
$spacers: ( "0": 0, "1": 0.25rem, "2": 0.5rem, "3": 1rem, "4": 1.5rem, "5": 3rem);
注意三点:
立即学习“前端免费学习笔记(深入)”;
"xs" 可以,"-1" 不行)0.5rem ✅,0.5 ❌(Sass 编译时会报 Invalid null operation)margin 和 padding 合在一个 map 里——它们语义不同、使用频率不同、响应式策略也常不一致@each,不是拼字符串生成 .mt-2、.mx-3 这类类名,靠的是两层遍历:
$spacing-types: ("m": "margin", "p": "padding");$spacing-sides: ("t": "top", "b": "bottom", "l": "left", "r": "right", "x": ("left", "right"), "y": ("top", "bottom"));@each $type-key, $type-prop in $spacing-types { @each $size-key, $size-val in $spacers { .#{$type-key}-#{$size-key} { #{$type-prop}: $size-val; } @each $side-key, $side-prop in $spacing-sides { @if type-of($side-prop) == "list" { .#{$type-key}#{$side-key}-#{$size-key} { @each $prop in $side-prop { #{$type-prop}-#{$prop}: $size-val; } } } @else { .#{$type-key}#{$side-key}-#{$size-key} { #{$type-prop}-#{$side-prop}: $size-val; } } } }}
关键点:
"x" 和 "y" 的值是 list,得用 @each 展开,不能写死 left/right
"margin-" + "top" —— Sass 不支持运行时字符串运算$prefix: "u-",然后写 .#{$prefix}#{$type-key}...
盲目给每个间距都配 sm:、md:、lg: 前缀,规则数会指数增长。真实做法是:
"4" 和 "5" 在 md 及以上生效@each $bp, $width in $breakpoints 包一层 @media,里面再套间距循环,而不是每个类都重复写媒体查询768px)或带引号字符串(如 "768px"),否则 @media (min-width: #{$width}) 会编译失败grep -r "m-[0-9]" src/ 看实际用了哪些类,删掉长期没被引用的尺寸档位最易被忽略的一点:$spacers map 的键顺序在 Sass 3.4+ 不保证稳定,别依赖 nth(map-keys($spacers), 1) 总是拿到 "0" —— 该用就显式写死或靠测试覆盖。