如何让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监听尺寸变化并同步更新网格轨道参数,可解决此问题:
实现思路
- 用
ResizeObserver精准监听每个网格项的尺寸变化 - 获取变化项所在的列/行索引
- 将对应轨道尺寸设置为当前项的实际尺寸,其余轨道保持
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.
相关产品推荐
相关产品推荐

