<p>Less中栅格偏移与推拉必须在编译期用变量、守卫和数学函数计算确定的margin-left或left/right值,公式为margin-left: (100% / @grid-columns) * @n + @grid-gutter-width / 2;push/pull需配合position: relative及列宽类使用,且各断点须独立循环生成并联动更新所有网格参数。</p>
Less 里实现栅格偏移(offset)和推拉(push/pull)不能靠运行时逻辑,必须在编译期用变量、守卫(when)和数学函数算出确定的 margin-left 或 left/right 值——否则生成的 CSS 就是错的,或者根本编译不过。
offset)必须基于列宽动态计算偏移的本质是给列加 margin-left,值等于「n 列宽度 + 对应 gutter」。硬写 margin-left: 16.666% 只对 12 列有效,且无法随 @grid-columns: 24 自动适配。
margin-left: (100% / @grid-columns) * @n + @grid-gutter-width / 2; ——注意这里要补半边槽宽,因为 .make-row 的负边距已抵消了列的左右 padding.col-md-offset-3 的宽度不能复用 .col-xs-offset-3,因为断点间 @grid-columns 或 @grid-gutter-width 可能不同xs 断点(即无媒体查询的默认偏移),导致小屏下偏移失效,iOS Safari 中尤其明显push/pull 类依赖 position: relative 和 left/right
Bootstrap 风格的推拉不是 Flex/Grid 排序,而是用 relative 定位微调视觉顺序,所以必须确保列容器有 position: relative,否则 left 不生效。
.col-md-push-2 编译后应为:left: (100% / @grid-columns) * 2;,不是 margin-left
pull 是反向操作:right: (100% / @grid-columns) * @n;,别写成 left: -X%——语义不清,且容易在 RTL 场景翻车.col-md-6.col-md-push-3 才有意义;单独用 .col-md-push-3 会把一个未设宽的元素往右推,但布局已塌陷Less 3.5 之前不支持 .each(),只能靠带守卫的递归 mixin 实现 offset 和 push 的批量生成。写错守卫条件会直接报 Recursive call to mixin 错误。
立即学习“前端免费学习笔记(深入)”;
.make-offset(@n, @total) when (@n > 0) { .col-offset-@{n} { margin-left: (100% / @total) * @n; } .make-offset((@n - 1), @total); }
.make-offset(0, @total) {},否则无限递归.make-offset(12, @grid-columns-sm);,而不是固定写死 12
移动端优先不是“先写 xs 偏移,再用 @media 覆盖”,而是每个断点都独立跑一遍偏移计算逻辑。否则会出现 .col-lg-offset-4 宽度还是按 xs 的 12 列算,实际在大屏 24 列系统里只占一半该占的空间。
.make-offset-for-breakpoint(@breakpoint, @cols, @gutter),然后用 @media (min-width: ~"@{max}") 包裹整个块if (@screen-md > 768px) —— Less 没有运行时 if,守卫只认变量值,不认单位比较push/pull 在断点切换时可能需要清零,比如小屏堆叠时不该有 left 偏移,得显式写 .col-sm-push-0 { left: 0; }
真正难的不是写对一个 offset 类,而是让所有断点下的偏移、推拉、列宽、行负边距、槽宽全部联动更新——任何一个变量改了,其他地方都得跟着重算,漏掉一处,网格就错位。