Kodokon kodokon.com

专家级网格:subgrid、auto-fit 与 minmax

无需媒体查询即可构建自适应网格,并用 subgrid 让嵌套组件在父级的轨道上对齐。

10 分钟 · 3 题

在 Kodokon 中打开本课

repeat(auto-fill, ...)repeat(auto-fit, ...) 会在容器宽度允许的范围内创建尽可能多的轨道。二者的区别只在项目数少于可能的轨道数时才显现:auto-fill 会保留空轨道(你的两张卡片停留在其最小尺寸,右侧留有空白),而 auto-fit把空轨道折叠为零——被占用的轨道由于设有 1fr 最大值,于是会吸收全部被释放出来的空间,你的两张卡片便横向铺满整个宽度。

CSS
.gallery-fill {
  display: grid;
  grid-template-columns: repeat(
    auto-fill, minmax(150px, 1fr)
  );
}
.gallery-fit {
  display: grid;
  grid-template-columns: repeat(
    auto-fit, minmax(150px, 1fr)
  );
}
在 900px 中放 2 个项目:fill 保留 6 条轨道(2 满 4 空),fit 折叠空轨道并把 2 个项目拉伸开。

有两个连资深开发者都会掉进去的 minmax() 陷阱。其一:当容器比 240px 更窄时,minmax(240px, 1fr) 会溢出——这个最小值是一道硬下限。惯用的修复方法是嵌套一个比较函数:minmax(min(100%, 240px), 1fr)。其二:单独的 1fr 等价于 minmax(auto, 1fr);这个 auto 最小值会让不可断行的内容(一个长 URL、一个 <pre>)把轨道撑得超过它应得的份额。minmax(0, 1fr) 则锁定了分配。

CSS
.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(100%, 240px), 1fr)
  );
}
无需任何媒体查询的标准响应式网格:即使窄于 240px 也绝不溢出。

subgrid 解决了嵌套组件之间对齐这一由来已久的难题。有了 grid-template-rows: subgrid,内层网格不会自行发明轨道:它会在自己所跨越的区域上采用父级的轨道。它还会继承父级的线名(并可添加自己的),以及 gap(它可以在本地覆盖)。经典场景是:一批卡片的标题、描述和页脚在卡片之间横向对齐,无论其内容长度如何——在 subgrid 之前这几乎无法干净地做到,因为每张卡片都是孤立地计算自己的高度。

CSS
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}
.card {
  grid-row: span 3;
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0.5rem;
}
每张卡片跨越父级的 3 行并采用它们:标题、文本和页脚在各卡片之间对齐。

知识检测

确认你已牢记本课的重点内容。

  1. 一个容器能容纳 6 条轨道,但只包含 2 个项目。auto-fill 和 auto-fit 有什么区别?
    • 没有区别,它们是同一个值的两个别名
    • auto-fill 保留 4 条空轨道;auto-fit 折叠它们,2 个项目被拉伸
    • auto-fit 总是比 auto-fill 创建更多轨道
  2. 一个用 grid-template-rows: subgrid 声明的元素究竟采用了什么?
    • 只有父级的行数
    • 在所跨越区域上父级的轨道尺寸和线名,gap 被继承但可覆盖
    • 父级的全部网格属性,包括它的具名区域
  3. 为什么要写 minmax(min(100%, 240px), 1fr) 而不是 minmax(240px, 1fr)?
    • 为了在每块屏幕上都保证 240px
    • 为了在容器窄于 240px 时避免溢出
    • 因为自 Grid Level 2 起 min() 在 repeat() 内部是强制的