直接写 margin: 12px 不够用,因项目需复用、响应式调整和设计系统统一缩放;硬编码导致后期修改困难且易错位。sass 的 @each 通过映射 $spacers 生成语义化间距工具类,如 .m-sm { margin: 8px; },支持扩展方向与断点,但需避免命名冲突与单位遗漏。

为什么直接写 margin: 12px 不够用
项目里边距经常要复用、响应式调整、按设计系统统一缩放——硬编码每个值,后期改一个间距就得全局搜 margin 和 padding,漏改两处就错位。Sass 的 @each 不是炫技,是把“12px / 16px / 24px / 32px”这种重复模式交给变量和循环管。
怎么用 @each 生成间距工具类
核心是定义一个间距映射(map),再遍历生成类名。别用数组——map 能绑定语义(比如 sm 对应 8px),后续加断点或主题色也方便。
常见错误:把 $spacers 写成 list 导致 @each $key, $value in $spacers 报错;或者忘了加单位,编译出 margin: 16 这种无效 CSS。
- 用 map 定义:
$spacers: ("xs": 4px, "sm": 8px, "md": 16px, "lg": 24px, "xl": 32px); - 遍历生成类:
@each $size, $value in $spacers { .m-#{$size} { margin: $value; } .mt-#{$size} { margin-top: $value; } .mr-#{$size} { margin-right: $value; } .mb-#{$size} { margin-bottom: $value; } .ml-#{$size} { margin-left: $value; } } - 如果需要响应式,
@media块里再套一层@each,别试图在同一个循环里混 media 查询
margin 和 padding 能共用同一套 map 吗
能,但得小心命名冲突。比如 .p-md 和 .m-md 都用 $spacers 没问题,但如果你扩展出 .mx-md(左右)和 .my-md(上下),就得确保 map 里没用 mx 当 key——否则 @each 会把 mx 当作一个独立尺寸,而不是方向修饰符。
更稳妥的做法是拆成两个 map:$spacer-scales(纯数值)和 $spacer-directions("x", "y", "t" 等),再用嵌套循环生成组合类。不过小项目用单 map + 手动列方向就够了,别过早抽象。
编译后 CSS 体积会爆炸吗
会,但可控。5 个尺寸 × 5 个方向 = 25 个类;加到 8 个尺寸就 40 个——对现代打包工具不是问题。真正要防的是:有人把字体大小、圆角、阴影全塞进同一个 @each 循环,结果生成几百行无用 CSS。
性能提示:@each 是编译时行为,不影响运行时,但冗余类会增大 CSS 文件。上线前用 PurgeCSS 删掉未使用的 .m-xs 类,比压缩循环逻辑更有效。
容易被忽略的是:这些类名一旦暴露给 HTML,就变成了隐性 API。比如别人写了个 class="m-lg",你哪天把 lg 从 24px 改成 20px,所有地方都悄悄变紧凑了——所以 map 的 key 名要有稳定性,别用 "big" "huge" 这种主观词。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











