根本原因是未设边界导致无效css生成,应改用map-keys+min()控制上限、白名单替代暴力遍历,并用@debug编译时验证。

为什么循环生成的CSS类数量失控
根本原因不是语法写错了,而是没设边界——@for $i from 1 through 100 看似干净,但项目里实际只用到 .mt-1、.mt-2、.mt-4 这三个类。其余97个规则全进打包产物,Lighthouse 直接标红 “Reduce unused CSS”。
- 栅格系统盲目循环
@for $i from 0 through 12→ 多出无效的.col-0,干扰选择器匹配逻辑 - 颜色工具类用数组
$colors: red, green, blue+@each→ 生成.text-red、.text-green、.text-blue,但 HTML 里只写了text-primary - 断点嵌套没过滤:
@each $bp, $w in $breakpoints套@for $i from 1 through 12→ 每个断点都输出全部12列,哪怕只有md和lg需要响应式
用 map-keys + min() 控制循环上限
当你要限制“只生成前 N 个颜色变体”或“只对主色系加 hover 类”,不能硬写 through 3 —— 因为 map 的 key 顺序不保证,且未来加新色会错位。
- 先取键列表:
$keys: map-keys($colors) - 再算安全上限:
$limit: min(3, length($keys)) - 最后循环取值:
@for $i from 1 through $limit { .text-#{nth($keys, $i)}:hover { ... } } - 注意:
nth()是 1-indexed,$i必须从 1 开始,不能写from 0
白名单替代暴力遍历
比“限制数量”更彻底的做法是放弃数字区间,直接声明真实需要的值。比如间距类不该是 1px 到 100px,而应按设计系统定义明确梯度。
- 定义白名单:
$spacing-scale: (xs: 0.25rem, sm: 0.5rem, base: 1rem, lg: 1.5rem, xl: 2rem) - 用
@each $name, $value in $spacing-scale生成.p-xs、.p-sm等,而非.p-1到.p-20 - 字体大小同理:
$font-sizes: (caption: 0.75rem, body: 1rem, title: 1.5rem),避免@for $i from 12 through 24导致视觉节奏断裂 - 这样生成的每个类名都有语义,DevTools Coverage 面板一眼能看出哪些真被用了
编译时用 @debug 快速验证生成逻辑
@debug 不输出 CSS,只打日志,是定位冗余生成最轻量的手段。别等构建完再查 Coverage 面板。
- 在循环开头加:
@debug "Generating .mt-#{$i} for #{$i}rem"; - 执行
sass input.scss --no-source-map,终端立刻看到所有生成项 - 发现
"Generating .mt-50 for 50rem"这种明显超纲的日志,马上回头改through上限或换 map - 配合 CI 脚本:
sass input.scss 2>&1 | grep "Generating" | wc -l可做体积基线校验
真正难的不是写出循环,而是确认每一行输出 CSS 都有对应 HTML 使用。map 结构、白名单、@debug 日志这三样东西缺一不可——少一个,体积就悄悄膨胀。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











