推荐用列表+@each遍历$spacers等map生成间距/字体工具类,避免硬编码@for;加前缀隔离命名、控制输出维度与断点、联动line-height、禁用!important,确保可维护性与性能。

用 @for 生成间距工具类时,起始值和步长别硬写死
直接写 @for $i from 1 through 4 看似简单,但实际项目里间距常要支持 px、rem、响应式断点,甚至跳着来(比如只出 md 和 lg)。硬编码会让后续加个 2.5rem 都得改循环逻辑。
- 推荐用列表 +
@each或带偏移的@for:比如$spacers: (xs: 0.25rem, sm: 0.5rem, md: 1rem, lg: 1.5rem, xl: 2rem),再遍历生成.m-xx、.p-xx - 注意单位转换:Sass 中
1 * 0.25rem是合法的,但"1" + "rem"是字符串拼接,会失效 - 别在循环里嵌套媒体查询——每个断点都跑一遍
@for会让 CSS 体积指数级膨胀;应该先循环生成基础类,再用@media包一层统一覆盖
@for 生成字体大小工具类,font-size 的缩放不是线性叠加
很多人以为 @for $i from 12 through 24 { .fs-#{$i} { font-size: #{$i}px; } } 就完事了,但真实排版中字号是按比例阶梯增长(如 12 → 14 → 16 → 18 → 20 → 24),不是等差数列。盲目线性生成会导致视觉节奏断裂,小字号挤、大字号跳。
- 用 map 显式定义字号层级:
$font-sizes: (xs: 0.75rem, sm: 0.875rem, base: 1rem, lg: 1.125rem, xl: 1.25rem, xxl: 1.5rem) - 避免直接输出
px:现代项目基本用rem或em,且需配合html { font-size: 100% }保证基准一致 - 别忘了
line-height联动:字号变大时,行高也该微调,否则文字发“虚”。可搭配map-get($line-heights, $key)同步注入
生成的工具类命名冲突,!important 不是解药
批量产出的 .m-4、.mt-2 等类名一旦和第三方 UI 库(如 Bootstrap、Tailwind)撞车,样式就可能被覆盖。有人图省事加 !important,结果调试时发现某个 margin-bottom 死活不生效,查半天才发现是自己生成的类在全局 scope 里悄悄干掉了组件内部的 mb-0。
- 加前缀隔离:用
$prefix: "u-",生成.u-m-2、.u-text-lg,从根源上避免冲突 - 控制输出范围:用
@if map-has-key($config, "enable-spacing")这类开关,按需开启某类工具,而不是全量输出 - 不要把工具类塞进
:root或全局@layer utilities外层——Sass 没有原生 layer 控制,靠文件引入顺序决定优先级,容易失控
Sass 循环生成的 CSS 体积暴增,怎么压?
一个 5 层断点 × 10 个间距值 × 4 方向(m/p/mt/pt…)的组合,轻松产出上千行 CSS。开发时看不出问题,但打包后发现 main.css 多了 80KB,首屏渲染卡顿。
立即学习“前端免费学习笔记(深入)”;
- 删掉不用的方向:多数项目根本不需要
mr-3或pb-1,用$directions: (m: margin, p: padding)控制生成维度 - 用
@at-root把工具类提到最外层,避免嵌套污染选择器权重,减少重复声明 - 上线前走一遍
cssnano或esbuild --minify-css,但别依赖压缩——冗余类本身就在浪费解析时间
真正难的不是写出那个 @for 循环,而是想清楚哪些值必须精确控制、哪些可以裁剪、哪些要留扩展口。生成工具类不是为了“多”,而是让团队在约束里快速达成一致。稍不留意,自动生成就成了自找麻烦。










