最近在重构一个配置页的卡片布局,第一次认真使用 CSS Grid 的 minmax() 和 auto-fit,把理解过程记录下来。

从媒体查询说起

以前的响应式套路是 flex 布局加一组断点:手机上单列、平板上两列、桌面三列。问题在于断点是「猜」出来的——它基于流行设备尺寸,而不是内容本身。内容一改、加一个侧边栏,断点就可能全部失效。

minmax(240px, 1fr) 在做什么

minmax(min, max) 定义轨道尺寸的取值范围:轨道至少 240px,若容器还有剩余空间,则所有轨道平分剩余空间(1fr 的含义)。

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

repeat(auto-fit, ...) 让浏览器根据容器宽度自动决定放几列:容器宽放 3 个 240px 的轨道就放 3 个,放 5 个就放 5 个——不需要任何断点。

auto-fit 与 auto-fill 的区别

两者都会按容器宽度创建足够多的轨道,区别在于空轨道的处理:

  • auto-fill:保留空轨道,剩余空间由已有的 1fr 轨道平分,空轨道只是空占位;
  • auto-fit:折叠空轨道,剩余空间全部分给非空轨道,视觉上更饱满。

卡片数量刚好填满时两者表现一致;卡片不满时 auto-fit 通常是想要的效果。

一个容易踩的坑

minmax 的第一个值是硬下限:容器窄于 240px 时轨道不会继续收缩,而是溢出。在窄屏上可以配合 min() 兜底:

grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));

小结

能用一个 minmax 解决的布局,就别堆一串媒体查询。让布局跟随内容而不是跟随设备,是 Grid 带来的思路转变。