PAYATHON 2026

如何让 CSS Grid 的高度只由第一列决定,并保持第二列卡片等高?

数据小许

可以继续使用绝对定位,在滚动容器内增加一层 Grid:外层 .wrapper 限制可见高度并负责滚动,内层 .cards 使用自动高度和 grid-auto-rows: 1fr,让卡片等高。

第一列决定外层 Grid 的高度,第二列的卡片则可以在滚动区域内向下展开。

为什么原来的卡片没有保持等高?

原始结构中,第二列的内容参与外层 Grid 的行高计算,长列表会把整行撑高。

改用绝对定位后,长列表不再撑高外层 Grid,但 .wrapper 同时具有 height: 100% 和 display: grid,卡片网格的高度因此受到限制。

1fr 单独作为轨道尺寸时相当于 minmax(auto, 1fr)。高度受限、内容放不下时,各行内容的最小尺寸可能不同,因此不能保证所有行等高。高度自动、可用高度不确定时,Grid 会根据内容计算共同的 fr 尺寸。这里每张卡片各占一行,每行都是 1fr,可以得到等高的行。相关计算规则见 CSS Grid 规范。

修改 HTML:增加卡片网格层

在第二个示例的 .wrapper 内增加 .cards,把原来的所有 .card 移进去。下面展示前两张卡片,其余卡片按相同方式保留:

<div class="app">
  <div class="first">
    <div class="resizable">This is resizable.</div>
  </div>

  <div class="second">
    <div class="wrapper">
      <div class="cards">
        <div class="card">
          <div class="name">Zog Blorpton</div>
          <div class="job-title">
            Chief Button Alignment Officer, Button Engineering
          </div>
        </div>

        <div class="card">
          <div class="name">Luma Sparklefizz</div>
          <div class="job-title">
            Senior Unicorn Logistics Manager, Mythical Operations
          </div>
        </div>

        <!-- 其余 .card 放在这里 -->
      </div>
    </div>
  </div>
</div>

替换布局 CSS

用下面的规则替换原有布局规则,原来的 .card、.name 和 .job-title 样式可以保留:

* {
  box-sizing: border-box;
}

.app {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 3fr);
  align-items: stretch;
  gap: 0.5em;
  width: 700px;
}

.first {
  height: 300px;
  resize: vertical;
  overflow: auto;
  background: lightgray;
}

.second {
  position: relative;
  min-width: 0;
  min-height: 0;
}

.wrapper {
  position: absolute;
  inset: 0;
  overflow: auto;
  background: lightgray;
}

.cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-auto-rows: 1fr;
  gap: 0.5em;
  height: auto;
  min-height: 100%;
  padding: 0.5em;
}

需要完整替换旧的 .wrapper 规则,把原来的 display: grid、grid-auto-rows、gap 和 padding 移到 .cards,避免旧规则继续影响布局。

.wrapper 通过 inset: 0 填满第二列。它脱离正常流,内部列表不会再为外层 Grid 提供内容高度。绝对定位元素不参与 Grid 轨道尺寸计算的规则见 CSS Grid 中的绝对定位。

.cards 保持 height: auto,让等高行按内容展开;min-height: 100% 则让卡片较少时仍能填满滚动区域。卡片较多时,内层网格可以超过这个最小高度,由 .wrapper 显示滚动条。

使用时注意什么?

  • 保留 .cards 的自动高度,不要给它添加 height: 100% 或固定的 max-height,否则会再次限制卡片网格的可用高度。
  • minmax(0, 1fr) 用于行高时,允许行收缩到内容放不下的高度,可能导致文字溢出;这里的卡片行继续使用 1fr。
  • 示例中的 300px 是第一列的初始高度,来自原问题的第二个示例。拖动 .first 的调整手柄后,第二列的滚动区域会随整行高度变化。
  • 原代码中设置了 resize: vertical 的元素是 .first;.resizable 只是它里面的普通子元素。
  • 如果不需要卡片较少时填满右侧高度,可以删除 .cards 的 min-height: 100%,保留按内容计算的等高行。

备注:内容仅供参考。