不能直接用 @for $i from 0 through 12 生成列类,因为 .col-0 无语义、干扰选择器优先级、增加无效 CSS;应从 1 开始循环,严格对齐 1–12 列设计规范,并用 percentage($i / 12.0) 避免整数除法归零。

为什么不能直接用 @for $i from 0 through 12 生成列类
因为 .col-0 没有意义,也不符合 Bootstrap、Tailwind 等主流约定。它既不对应任何可用布局语义,又可能干扰选择器优先级(比如被 [class*="col-0"] 误匹配)。更关键的是,Sass 编译时多出一条无效规则,CSS 体积无谓增加,且 DevTools 里难以察觉。
正确做法是明确从 1 开始:@for $i from 1 through 12。这直接对应设计系统中实际支持的列数范围(1–12),避免生成冗余类,也和栅格逻辑对齐。
- 若项目需支持 offset/push,它们的数值范围通常与列数一致,可复用同一循环变量
- 列数范围必须严格对齐设计规范:只支持 12 列,就别循环到 16;否则生成的
.col-13类在 HTML 中永远不会被使用,纯属噪音 - 不要为“兼容旧习惯”而保留
col-0——它不是占位符,是错误信号
percentage($i / 12) 为什么必须写成 percentage($i / 12.0)
Sass 默认执行整数除法:1 / 12 得 0,percentage(0) 输出 0%。结果所有列宽全归零,页面内容塌陷,但控制台和 DevTools 不报错,极难定位。
加 .0 是强制浮点运算的最小代价操作,确保 percentage($i / 12.0) 输出如 8.33333% 这类有效值。
立即学习“前端免费学习笔记(深入)”;
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
- 更健壮的做法是提前算好单位:
$col-unit: 100% / $grid-columns;,再用width: calc(#{$col-unit} * #{$i});,避免重复计算和精度丢失 - 别依赖浏览器四舍五入:
calc(100% / 7)在 Chrome/Firefox/Safari 下可能有 0.1px 渲染偏差 - 如果用了
gap,记得从总宽里减去 gutter 占位,否则列间距会塌陷
响应式断点嵌套时,@each 和 @for 谁包谁?
必须外层 @each $bp-name, $bp-value in $breakpoints,内层 @for $i from 1 through 12,且 @for 必须放在 @media (min-width: $bp-value) 内部。
反着来(@for 包 @each)会导致每个列数都重复声明全部断点,12 列 × 5 断点 = 60 条规则,其中大量冗余(比如 .col-md-6 和 .col-lg-6 宽度相同时仍重复输出)。
- 断点必须定义为 map:
$breakpoints: ("sm": 576px, "md": 768px, "lg": 992px);,不能硬写@media (min-width: 768px) - 如果某断点下无需响应式列(如移动端强制单列),跳过该
@each分支,别硬塞空@media - 所有断点变量和循环逻辑必须放在同一个
.scss文件中;@use后跨文件嵌套@media会丢失包裹,最终输出裸 CSS 类名
@at-root 是防止嵌套污染的唯一解
在某个选择器内部写 @for(比如 .container { @for ... }),生成的类会变成 .container .col-sm-3,完全失去全局性,无法被 HTML 直接调用。
必须用 @at-root 把循环输出提回顶层,确保生成的是 .col-sm-3 这类独立选择器。
-
@at-root不是可选优化,是作用域隔离的刚性要求 - 漏掉它,整个栅格系统在 HTML 中根本无法生效,但 Sass 编译仍成功,容易误判为“逻辑没问题”
- 如果后续要切到 24 列,只需改
$grid-columns变量,不用重审循环结构——前提是当前逻辑已用@at-root正确隔离
配置驱动的栅格生成,真正复杂的地方不在循环语法,而在变量之间的耦合:断点 map 的键名必须和容器宽度 map 严格一致,列数变更必须同步更新 offset/push 的上限,@at-root 的位置稍偏一点,输出就全错。这些不是编译报错能捕捉的,得靠人眼核对生成的 CSS 是否按预期包裹、命名是否干净、类是否存在冗余。

















