React Next.js动态Grid布局:实现可扩展的卡片展开效果
动态实现网格卡片展开布局的方案
核心思路:放弃静态grid-area,改用动态计算grid-row + 响应式列数控制
不用手动定义grid-A1这类固定类,而是通过计算卡片索引来动态设置行位置,同时利用Tailwind的响应式工具和CSS变量适配不同断点的列数,彻底摆脱行数限制。
步骤1:配置网格容器
确保容器使用自动行高,让行高随内容自适应,避免固定行高限制扩展:
<div className="grid gap-4 grid-cols-5 md:grid-cols-2 grid-template-rows:auto"> {/* 卡片及展开内容将渲染在这里 */} </div>
这里grid-cols-5对应桌面端5列布局,md:grid-cols-2对应移动端2列布局(可根据你的断点需求调整)。
步骤2:动态计算卡片行位置
渲染卡片时,根据当前断点的列数,计算主卡片所在的行,展开的子卡片直接放在主卡片的下一行:
// 根据窗口宽度获取当前列数,或用CSS变量优化(见步骤3) const getCurrentColumns = () => { return window.innerWidth >= 768 ? 5 : 2; }; // 遍历渲染卡片 cards.map((card, index) => { const columns = getCurrentColumns(); const cardRow = Math.floor(index / columns) + 1; // 计算主卡片所在行 return ( <> <div className="p-4 bg-white rounded shadow cursor-pointer" style={{ gridRow: cardRow }} onClick={() => setSelectedIndex(selectedIndex === index ? null : index)} > <h3>{card.title}</h3> <button>{selectedIndex === index ? '收起' : '展开'}</button> </div> {/* 展开的子卡片,跨整行 */} {selectedIndex === index && ( <div className="col-span-full p-4 bg-gray-50 rounded shadow" style={{ gridRow: cardRow + 1 }} > {card.content} </div> )} </> ); })
步骤3:用CSS变量优化断点适配(可选)
避免JS硬编码断点值,用CSS变量统一管理不同断点的列数:
/* 在全局样式或Tailwind的@layer base中添加 */ :root { --grid-cols: 5; } @media (max-width: 768px) { :root { --grid-cols: 2; } }
然后在JS中读取变量,无需判断窗口宽度:
const columns = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--grid-cols'));
步骤4:自定义Tailwind工具类简化样式(可选)
如果不想写内联样式,可以自定义工具类配合CSS变量:
@layer utilities { .card-row { grid-row: var(--card-row); } .expanded-row { grid-row: calc(var(--card-row) + 1); } }
组件中使用方式:
<div className="p-4 bg-white rounded shadow cursor-pointer card-row" style={{ '--card-row': cardRow }} onClick={() => setSelectedIndex(selectedIndex === index ? null : index)} > <h3>{card.title}</h3> <button>{selectedIndex === index ? '收起' : '展开'}</button> </div> {selectedIndex === index && ( <div className="col-span-full p-4 bg-gray-50 rounded shadow expanded-row"> {card.content} </div> )}
方案优势
- 无需手动配置任何固定行类,新增卡片自动适配行数
- 响应式列数仅需在一处修改,移动端多列场景也能自动计算行位置
- 网格行高随内容自适应,不会出现内容溢出或空白浪费问题
内容的提问来源于stack exchange,提问作者Craig P
相关产品推荐
相关产品推荐

