不能只写 .col-1 到 .col-12,因为需叠加 offset/push/pull 三类偏移及 sm/md/lg/xl 四个断点,类名将超100个;且修改列宽比例(如 $i/12 改为 $i/16)时须同步更新所有断点下的宽度、偏移、推拉,易遗漏导致布局错位;scss 的 @for 和嵌套可集中逻辑、确保生成结果可预测、可维护。

为什么不能只写 .col-1 到 .col-12?
直接手写 .col-1 到 .col-12 看似简单,但实际要覆盖 offset、push、pull 三类偏移类,再叠加 sm、md、lg、xl 四个断点,类名数量会迅速膨胀到 100+ 行。更关键的是:改一个列宽比例(比如从 $i / 12 改成 $i / 16),所有断点下的宽度、偏移、推拉都得同步改——漏一个,布局就错位。SCSS 的 @for 和嵌套不是“省事”,而是把逻辑收敛到一处,让生成结果可预测、可维护。
如何用 @for 生成基础列宽类(.col-*)
核心是控制列数 $i 并算出对应宽度百分比。注意:SCSS 中 1 / 12 是整数除法,结果为 0,必须写成 $i / 12.0 或启用 precision 配置。推荐统一用小数避免陷阱:
@for $i from 1 through 12 {
.col-#{$i} {
flex: 0 0 percentage($i / 12.0);
}
}
-
flex: 0 0 ...表示不放大、不缩小,仅按基础尺寸占位,符合栅格语义 - 不用
width而用flex-basis,确保在 Flex 容器中行为一致 - 如果需兼容 IE10/11,可额外加
max-width和min-width双保险
怎样安全添加响应式前缀(如 md-col-6)?
响应式前缀不是简单拼字符串,必须包裹在对应媒体查询内,且父容器需已启用 display: flex。否则加了 md-col-6 也无效——Flex 上下文不存在。
$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
);
@each $name, $value in $breakpoints {
@media (min-width: $value) {
@for $i from 1 through 12 {
.#{$name}-col-#{$i} {
flex: 0 0 percentage($i / 12.0);
}
}
}
}
- 不要把
@media写在循环内部(性能差、编译慢),而是在外层包裹整个断点逻辑 - 所有生成的类都必须独立声明
flex行为,不能依赖外部类注入display: flex - 若项目需支持 RTL,记得在断点内补上
dir: rtl下的flex-direction: row-reverse变体
offset/push/pull 类怎么生成才不冗余?
这类偏移的本质是设置 margin-left(offset/push)或 margin-right(pull),但 push 和 pull 在现代 Flex 布局中基本被 order 和 justify-content 取代;真正需要的是 offset(留白)和 push(向右推)两种。关键是:避免生成 .col-md-offset-0 这类无意义类名。
@each $name, $value in $breakpoints {
@media (min-width: $value) {
@for $i from 1 through 11 {
.#{$name}-offset-#{$i} {
margin-left: percentage($i / 12.0);
}
.#{$name}-push-#{$i} {
margin-left: percentage($i / 12.0);
}
.#{$name}-pull-#{$i} {
margin-right: percentage($i / 12.0);
}
}
}
}
- 从
1开始循环,跳过0——它不产生样式,纯属噪音 -
push和pull的语义易混淆,建议只保留offset+ms-auto/me-auto(Bootstrap 5 风格)替代push/pull - 如果用到
gap,注意offset类与gap叠加可能导致总宽度超限,需在文档中标明互斥使用场景
flex: 0 0,或者把 @media 错放到循环里,编译出来的 CSS 就可能在某个断点下完全失效。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











