@for 循环仅在编译时生成静态 CSS,必须用 through 而非 to 保证闭区间、加 .0 强制浮点运算避免整除截断,并用 @each 包裹断点实现响应式类名,不可替代运行时响应式逻辑。

@for 循环本身不“复杂”,它只做一件事:在编译时生成固定规则。所谓“复杂网格系统”,其实是靠嵌套、变量和约定堆出来的——不是循环有多聪明,而是你如何组织它。
为什么 @for $i from 1 through 12 必须用 through 而不是 to
因为 to 是左闭右开区间:@for $i from 1 to 12 只生成 .col-1 到 .col-11,漏掉关键的 .col-12。实际项目里,12 列是常见栅格上限,漏掉它会导致大屏布局直接塌陷,且 DevTools 里看不出明显报错,排查成本极高。
-
through是闭区间,语义清晰、行为确定,所有主流框架(Bootstrap、Foundation 源码)都这么写 - 如果后续要切到 24 列系统,改
1 through 12为1 through 24即可,不用动逻辑 - 别写
to 13图省事——基数一变,to就容易错位
percentage($i / 12.0) 里的 .0 不是可选,是必须
Sass 默认整数除法会截断小数:1 / 12 直接得 0,percentage(0) 输出 0%,结果就是所有列宽全为 0。加 .0 强制浮点运算,才能得到正确值。
- 错误写法:
percentage($i / 12)→.col-1 { width: 0%; } - 正确写法:
percentage($i / 12.0)→.col-1 { width: 8.33333%; } - 更健壮做法:提前定义
$col-unit: 100% / $grid-columns;,再用calc(#{$col-unit} * #{$i}),避免重复计算和精度漂移
响应式类名必须外层 @each 断点、内层 @for 列数
断点映射必须用 @each $name, $width in $breakpoints 包住整个 @for,否则 CSS 体积爆炸、规则冗余、顺序混乱。
立即学习“前端免费学习笔记(深入)”;
- 反着来(
@for包@each)会导致每个列数都重复声明全部断点,比如.col-1下塞进 sm/md/lg/xl 四套媒体查询,实际只需要一套 - 断点 map 必须在同一个文件里定义并使用,跨文件
@import后再嵌套,@media会丢失包裹,输出裸规则 - 如果某个断点下不需要响应式列(如移动端强制单列),直接跳过该
@each分支,别硬塞空@media
别指望 @for 实现运行时响应式
@for 编译后只输出静态 CSS 规则,比如 .col-md-4 { width: 33.33333%; } —— 这个百分比是硬编码进去的,浏览器加载后就固定了,不感知视口变化,也不随容器缩放。
- 真正响应式行为(小屏下单列、中屏下三列)必须靠
@media套多套规则,或用grid-template-columns: repeat(auto-fit, minmax()) -
@for只适合生成基础栅格骨架,比如.col-6、.col-md-4类,但每个类内部仍是固定值 - 如果需要“根据当前容器宽度自动选列数”,
@for无能为力——那是container queries或 JS 的事
真正容易被忽略的,是编译期和运行时的界限。SCSS 再怎么循环,也变不出浏览器实时计算的列数;你写的每一行 @for,最终都变成一行行死的 CSS。想清楚这点,就不会在循环里塞 calc()、JS 表达式,也不会期待它自动适配屏幕旋转。


















