栅格系统必须用参数化 mixin 而非静态类名,以实现列宽逻辑集中、响应式断点统一、间距与列数灵活调整;需通过变量定义断点和栅格配置,用 each() 遍历生成响应式类,gutter 用 padding 实现,布局模型应解耦以兼容不同浏览器。

栅格系统必须用参数化 mixin 而不是静态类名
直接写 .col-1、.col-2 这类固定类名,看似快,实则不可维护:列宽逻辑分散、响应式断点无法统一调整、换一套间距或列数就得全量重写。Less 的核心优势是变量 + mixin,栅格必须封装成带参数的 .make-col() 和 .make-row()。
常见错误是把栅格写成一堆独立 class,结果媒体查询重复出现、@media 嵌套层级失控。正确做法是定义一套断点变量,所有响应式行为由 mixin 内部根据参数生成:
@grid-columns: 12;
@breakpoints: (
sm: 576px,
md: 768px,
lg: 992px
);
<p>.make-col(@span: 1, @columns: @grid-columns) {
flex: 0 0 calc(100% / @columns * @span);
}</p><p>.make-row() {
display: flex;
flex-wrap: wrap;
margin-left: -(@grid-gutter-width / 2);
margin-right: -(@grid-gutter-width / 2);
}响应式列宽必须用 map 遍历生成,不能手写每个断点
手写 @media (min-width: 768px) { .col-md-3 { ... } } 三遍?一旦新增断点或修改某一层规则,极易漏改。Less 的 each() 函数配合 map 是唯一可靠方式。
- 定义断点 map:
@breakpoints: (sm: 576px, md: 768px, lg: 992px); - 在 mixin 中遍历:
.make-col-responsive(@span, @breakpoint-map) { each(@breakpoint-map, { .col-@{key}-@{span} { @media (min-width: @@value) { .make-col(@span); } } }); } - 调用时自动产出所有断点下的类:
.make-col-responsive(4, @breakpoints);
注意:Less 3.5+ 才支持 each();旧版本需降级为循环变量拼接,但可读性差、调试困难。
立即学习“前端免费学习笔记(深入)”;
栅格间距(gutter)必须通过 padding 实现,而非 margin
用 margin 控制 gutter 会导致最后一行子元素右侧多出空隙、flex 换行错位、嵌套栅格塌陷。标准解法是给 row 设负 margin,给 col 设正 padding —— 这正是 Bootstrap 的做法,也是 Less 中最易复用的模式。
- 定义统一 gutter 变量:
@grid-gutter-width: 1rem; - row 左右负边距抵消 gutter:
margin-left: -(@grid-gutter-width / 2); - col 内边距承载 gutter:
padding-left: @grid-gutter-width / 2; padding-right: @grid-gutter-width / 2; - 避免在 col 上用
margin,否则与 flex 的justify-content冲突
避免在 mixin 中硬编码 display: flex
不是所有项目都能用 Flexbox —— 某些遗留系统仍需 IE10/11 支持,得回退到 float 或 inline-block。把 display: flex 写死在 .make-row() 里,等于锁死布局模型。
正确做法是拆分职责:
-
.make-row-base():只处理 gutter 和容器通用样式 -
.make-row-flex():额外加display: flex和相关属性 -
.make-row-float():提供zoom: 1和overflow: hidden清浮动
使用者按需组合:.make-row-base(); .make-row-flex();。这样既保持复用性,又不强加技术选型。
真正难的不是写出栅格,而是让每处 @grid-columns、@grid-gutter-width、@breakpoints 都能被下游模块安全覆盖 —— 变量作用域和 import 顺序稍有不慎,就会导致某层栅格突然变宽或断点失效。


















