sass在编译期计算列宽百分比(如percentage($i / 12)),再用calc()运行时减去gutter;不能在calc()内直接写sass变量,须用#{}插值注入已算好的值,避免单位混用和整除误差。

用 calc() 和 Sass 变量组合实现响应式列宽
纯 CSS 的栅格系统无法动态计算列宽,但 Sass 在编译期能做算术——关键不是“运行时自动计算”,而是“编译时按规则生成精确值”。calc() 留给浏览器处理剩余部分(比如减去 gutter),Sass 负责把 $columns、$gutter、$container-width 这些变量转成可维护的类名和宽度值。
常见错误是试图在 @for 循环里用 calc(100% / #{$i}),这会直接输出字符串,浏览器无法解析——Sass 不会把变量代入 calc() 内部再求值,它只拼字符串。
- 正确做法:Sass 计算出具体数值(如
16.66667%),再套一层calc(#{$val} - #{$gutter})处理边距 - 使用场景:固定列数栅格(如 12 列),需输出
.col-3、.col-8等类 - 注意
percentage()函数返回带%的字符串,可直接用于 width 声明
用 @for 循环生成 .col-* 类时如何避免整除误差
Sass 的除法默认是浮点运算,但 100 / 12 这种结果(8.333333...%)在 CSS 中必须足够精确,否则多列相加会溢出容器。浏览器对小数位容忍度低,尤其在 flex 或 grid 下容易换行。
实操建议:
- 用
round(100% / $columns * $span, 5)控制小数位数,5 位基本够用 - 不要用
math.div(100%, $columns) * $span(旧版div()有精度问题),优先用/操作符 - 如果用
grid-template-columns: repeat($columns, 1fr)配合grid-column: span #{$span},就完全绕开百分比计算——这是更现代、更可靠的替代方案
为什么 calc() 里不能直接写 Sass 变量
因为 calc() 是 CSS 函数,运行在浏览器渲染阶段;Sass 变量在编译阶段就被替换成字面量。写成 width: calc(100% / $cols) 会报错:Invalid CSS after "...l(100% / ": expected expression。
必须显式拼接:
@for $i from 1 through $columns {
.col-#{$i} {
width: calc(#{percentage($i / $columns)} - #{$gutter});
}
}
这里 #{...} 是插值语法,把 Sass 表达式结果(如 "8.33333%")注入到字符串中。漏掉 # 就会原样输出 $i / $columns,导致 CSS 无效。
移动端断点嵌套时,@media 内部的循环为何不生效
不是不生效,而是生成逻辑错了:如果在 @media (max-width: 768px) 里重复写一套 @for,会产出两套完全相同的类名(如又一个 .col-4),后者覆盖前者——但样式没变,因为宽度值一样。
真正需要的是“不同断点下,同一类名对应不同宽度”。所以应把断点作为外层控制,循环放内层:
- 先定义
$breakpoints: (sm: 576px, md: 768px, lg: 992px) - 外层遍历
@each $name, $bp in $breakpoints,内层再@for生成类 - 类名加前缀,如
.col-md-4,避免冲突 - 注意
min-width和max-width的断点区间别重叠,否则媒体查询可能意外触发多次
最易被忽略的是 gutter 的单位一致性:如果 $gutter 是 1rem,那所有 calc() 里的减法必须也用 rem,混用 px 和 rem 会导致计算失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











