必须用 through 而非 to,因 to 是开区间会漏掉 .col-12;percentage 计算需加 .0 避免整数除法归零;响应式断点须外层 @each、内层 @for;grid-column-start 范围为 1 至 $grid-max-columns + 1。

@for 是生成网格类最直接、最可控的方式,但它不是“写一次就完事”的魔法——变量定义、边界控制、嵌套顺序稍有偏差,编译出的 CSS 就可能漏类、错宽、覆盖失效,甚至上线后才发现大屏布局崩了。
为什么必须用 through 而不是 to
因为 to 是开区间,@for $i from 1 to 12 只生成 .col-1 到 .col-11,漏掉关键的 .col-12。而 12 列是主流栅格系统的上限,漏掉它会导致最大宽度容器无法铺满,DevTools 里查不到报错,只能靠肉眼比对布局。
-
through是闭区间:@for $i from 1 through 12真正产出 12 个类,语义清晰,改列数时(比如切到 24 列)只需调$grid-max-columns: 24,不用动循环逻辑 - 有人写
to 13图“结果一样”,但这是掩耳盗铃:一旦后续把12换成变量$cols,to $cols + 1就容易和through $cols混淆,团队协作时极易出错 - 所有主流框架源码(Bootstrap、Tailwind)都统一用
through,这不是偏好,是经过大规模验证的约定
percentage($i / 12.0) 里的 .0 不是可选项
Sass 默认整数除法会截断小数,1 / 12 直接得 0,percentage(0) 输出 0%——所有列宽全归零,页面空白。加 .0 强制浮点运算,才能得到正确值。
- 错误写法:
width: percentage($i / 12)→.col-1 { width: 0%; } - 正确写法:
width: percentage($i / 12.0)→.col-1 { width: 8.33333%; } - 更健壮做法:提前定义
$col-unit: 100% / $grid-columns;,再用width: calc(#{$col-unit} * #{$i});,避免重复除法,也方便后期切换单位(如 rem 或 vw)
响应式断点必须外层 @each、内层 @for
如果反过来(@for 包 @each),每个列数都会重复声明全部断点,CSS 体积翻 N 倍,且大量规则冗余无效。更重要的是,Sass 的 @media 必须在同一个 .scss 文件里完成包裹,跨文件引入断点 map 后再嵌套,@media 会丢失,输出裸规则。
立即学习“前端免费学习笔记(深入)”;
- 正确结构:
@each $name, $width in $breakpoints { @media (min-width: #{$width}) { @for $i from 1 through $grid-max-columns { .col-#{$name}-#{$i} { width: percentage($i / $grid-max-columns * 1.0); } } } } - 断点 map 必须是真实 map(
("sm": 576px, "md": 768px)),不能是 list;否则@each迭代顺序不可控,移动端优先逻辑可能失效 - 若某断点下不需响应式列(如移动端强制单列),直接跳过该
@each分支,别硬塞空@media块
grid-column-start 类的数值范围容易被忽略
grid-column-start 最小值是 1,最大值是 $grid-max-columns + 1(因为可跨到最后一个轨道线之后)。超出这个范围不会报错,但布局完全失效,且 DevTools 里看不出异常——元素还在 DOM,只是位置飘走。
- 安全写法:
@for $i from 1 through $grid-max-columns + 1,确保.col-start-13在 12 列系统中合法存在 - 别用
nth-child或 JS 思维去“动态算最大值”——Sass 编译期无 DOM,所有边界都靠变量约定 - 如果项目用了
grid-template-areas,这类col-start-类基本无效,得在文档里明确标注适用前提
真正麻烦的从来不是写几行 @for,而是变量怎么定、边界怎么卡、断点怎么嵌、类名怎么排——这些细节不抠清楚,生成的 CSS 看着整齐,跑起来却处处是坑。


















