在构建图片展示、商品列表或后台数据面板时,卡片墙是非常常见的界面形式。传统做法多用float或flex-wrap,但在容器宽度变化时需要写大量媒体查询,且最后一行经常对齐不齐。CSS Grid自带轨道划分能力,可以用极少量代码实现真正弹性的卡片墙。

一、Grid弹性卡片墙的核心属性
实现弹性卡片墙最关键的是grid-template-columns属性。过去我们习惯写死列数,例如grid-template-columns: repeat(3, 1fr)表示固定三列。但卡片墙希望列数随屏幕变,这时就要用到repeat()函数里的auto-fill关键字,以及定义最小最大宽度的minmax()函数。
auto-fill的意思是:浏览器根据容器宽度,尽可能多地填充列轨道。结合minmax(250px, 1fr),每一列最小250像素,最大占满剩余空间的一份。当容器只能放下两面列时,它自动变两列;能放五列时就五列。这样卡片墙天然响应式,不需要任何断点代码。
基础结构代码
下面是一段最简HTML结构,若干个卡片放在一个容器中:
<div class="card-wall"> <div class="card">卡片一</div> <div class="card">卡片二</div> <div class="card">卡片三</div> <div class="card">卡片四</div> </div>
对应的CSS只需要几行就能让上述结构变成弹性墙:
.card-wall {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 16px;
padding: 16px;
}
.card {
background: #f5f7fa;
border-radius: 8px;
padding: 20px;
min-height: 120px;
}
二、minmax与auto-fill的配合使用细节
minmax()的第一个参数设定了卡片能缩到多窄,第二个参数1fr表示弹性伸展。如果最小宽度设得太小,手机上字会挤;太大则桌面端列数少。一般卡片文字较多时,最小宽度设在220到280像素之间体验较好。
要注意auto-fill和auto-fit的区别。前者即使某行没填满也保留空轨道,后者会把空轨道折叠,让已有卡片拉伸占满。卡片墙通常用auto-fill保留视觉间距;若希望最后一行少量卡片撑满整行,可换auto-fit。下面演示两者差异的容器定义:
.wall-fill {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.wall-fit {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
在只有三张卡片且容器很宽时,auto-fill下会出现多个空白列,卡片本身宽度不变;auto-fit下三张卡片会被拉宽到平分整行。根据设计需求选择即可,误用常导致设计师抱怨卡片被不合理放大。
三、卡片内部弹性与对齐处理
Grid只管外层轨道,卡片内部若内容长度不一,底部会对不齐。可在卡片上再用Grid或Flex做内部纵向布局。例如让卡片标题固定,内容区伸展,底部按钮贴底:
.card {
display: flex;
flex-direction: column;
}
.card .body {
flex: 1;
}
.card .footer {
margin-top: 12px;
}
此外,用align-items: start可防止卡片被强行拉成等高;若希望视觉等高,则默认stretch即可。网格间距统一用grid-gap(新标准写作gap)控制,避免margin塌陷问题。
完整卡片墙示例
综合上述要点,下面是一个包含内部弹性的完整页面片段:
<style>
.wall {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 16px;
}
.wall .item {
display: flex;
flex-direction: column;
border: 1px solid #e3e8ef;
border-radius: 6px;
padding: 16px;
}
.wall .item .desc {
flex: 1;
color: #555;
}
</style>
<div class="wall">
<div class="item"><h4>标题A</h4><p class="desc">内容区域自动撑开</p><span>操作</span></div>
<div class="item"><h4>标题B</h4><p class="desc">短内容</p><span>操作</span></div>
</div>
四、与Flex方案的对比及注意事项
Flex的flex-wrap: wrap配合flex-basis也能做卡片流,但它是按项目依次排列,最后一行左对齐且无法感知整体列宽,常出现右边空隙。Grid的轨道模型从行和列二维控制,每行严格对齐,更适合墙状布局。
使用Grid时需注意旧版IE不支持相关函数,若项目要兼容IE需引入polyfill或降级为float。现代浏览器自2021年起已全面支持minmax与auto-fill。另外避免把minmax最小值设成百分比,某些场景下会计算异常,用固定像素更安全。
| 方案 | 响应式方式 | 最后一行对齐 | 代码量 |
|---|---|---|---|
| Float | 媒体查询 | 差 | 多 |
| Flex-wrap | flex-basis+百分比 | 一般 | 中 |
| Grid auto-fill | minmax自适应 | 优 | 少 |
通过上述方法,只用原生CSS就能交付一个健壮的弹性卡片墙,后续新增卡片无需调整任何布局样式,浏览器会自动重排轨道。