You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让CSS Grid结合resize实现行列双向缩放(含缩小)?

问题:CSS Grid网格项resize缩小无法同步调整整行列的解决方法

给CSS Grid的网格项设置resize: both时,拉伸操作能同步扩展对应列/行、收缩其余列/行,但缩小操作仅会让单个项变小,其余网格不受影响,导致布局出现空隙。如何让拉伸和缩小都能影响整个网格?

代码示例

CSS代码

.container {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-rows: repeat(2, 1fr);
  grid-template-columns: repeat(2, 1fr);
}

.container div {
  margin: 10px;
  resize: both;
  overflow: hidden;
  text-align: center;
  background-color: grey;
}

HTML代码

<html>
  <head>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="container">
      <div>One</div>
      <div>Two</div>
      <div>Three</div>
      <div>Four</div>
    </div>
  </body>
</html>

解决方案:JavaScript同步网格轨道尺寸

纯CSS无法实现该需求,因为resize仅修改单个元素尺寸,网格轨道不会自动响应缩小操作。通过JavaScript监听尺寸变化并同步更新网格轨道参数,可解决此问题:

实现思路

  1. 用ResizeObserver精准监听每个网格项的尺寸变化
  2. 获取变化项所在的列/行索引
  3. 将对应轨道尺寸设置为当前项的实际尺寸,其余轨道保持1fr自适应

完整实现代码

<html>
  <head>
    <style>
      .container {
        width: 100%;
        height: 100vh;
        display: grid;
        grid-template-rows: repeat(2, 1fr);
        grid-template-columns: repeat(2, 1fr);
        gap: 20px; /* 替换margin为gap,简化尺寸计算 */
      }

      .container div {
        resize: both;
        overflow: hidden;
        text-align: center;
        background-color: grey;
        padding: 10px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div>One</div>
      <div>Two</div>
      <div>Three</div>
      <div>Four</div>
    </div>

    <script>
      const container = document.querySelector('.container');
      const gridItems = container.querySelectorAll('div');
      const colCount = 2;
      const rowCount = 2;

      // 初始化轨道尺寸数组,默认1fr
      let colSizes = Array(colCount).fill('1fr');
      let rowSizes = Array(rowCount).fill('1fr');

      const resizeObserver = new ResizeObserver(entries => {
        entries.forEach(entry => {
          const item = entry.target;
          // 获取元素所在的网格列/行起始位置
          const colIndex = parseInt(getComputedStyle(item).gridColumnStart) - 1;
          const rowIndex = parseInt(getComputedStyle(item).gridRowStart) - 1;
          
          // 同步对应轨道的尺寸
          colSizes[colIndex] = `${entry.contentRect.width}px`;
          rowSizes[rowIndex] = `${entry.contentRect.height}px`;

          // 更新网格容器的轨道设置
          container.style.gridTemplateColumns = colSizes.join(' ');
          container.style.gridTemplateRows = rowSizes.join(' ');
        });
      });

      // 为每个网格项添加监听
      gridItems.forEach(item => resizeObserver.observe(item));
    </script>
  </body>
</html>

关键细节

  • 用gap替代margin,避免额外的尺寸计算,确保轨道尺寸与元素内容尺寸匹配
  • ResizeObserver能精准捕捉元素自身的resize操作,比窗口resize事件更高效
  • 同步轨道尺寸后,同列/行的所有元素会自动适配新的轨道大小,无论拉伸还是缩小都不会出现空隙

内容的提问来源于stack exchange,提问作者Adam B.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 20:16:09