卡片式设计几乎出现在所有现代网页中,商品列表、文章列表、图片墙都离不开卡片排列。当卡片数量超过一行能容纳的范围时,如何让它们自动换到下一行,并且保持间距均匀、对齐整齐,就是CSS布局要解决的核心问题。本文分别用flex布局和grid布局两种思路来实现,并分析各自的优缺点。

一、flex布局实现卡片自动换行
flex布局是最直观的方案。默认情况下,display: flex的容器会把所有子元素挤在同一行,即使空间不足也不会换行,这是很多人第一次写卡片布局时遇到的坑。原因在于flex-wrap属性的默认值是nowrap,需要手动改成wrap才能启用换行。
基础写法如下:
.card-container {
display: flex;
flex-wrap: wrap; /* 关键属性:允许换行 */
gap: 16px; /* 卡片之间的间距,水平和垂直方向都生效 */
}
.card {
width: 240px; /* 固定宽度,一行放不下自动换到下一行 */
background: #fff;
border: 1px solid #eee;
border-radius: 8px;
padding: 16px;
}
这段代码的效果是:容器宽度足够时,卡片横向排列;当剩余空间不足以再放下一个240px宽的卡片时,后面的卡片自动换到下一行。gap属性比传统的margin方案更干净,它只在元素之间产生间距,不会在容器边缘多出空白,也不需要处理首尾元素的margin清零问题。
如果希望卡片宽度不固定,而是平分一行空间,可以配合flex属性:
.card-container {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
flex: 1 1 240px; /* 基准宽度240px,可放大可缩小 */
min-width: 0; /* 防止内容撑破布局 */
}
这里flex: 1 1 240px的含义是:初始大小240px,空间富余时放大,空间不足时缩小。这样每行卡片数量会随容器宽度动态变化,最后一行的卡片如果数量较少,会被拉伸占满整行。如果不希望最后一行被拉伸,可以给卡片设置max-width,或者改用grid布局。
二、grid布局实现自适应网格
grid布局天生就是为二维排列设计的,处理卡片换行比flex更简洁。核心技巧是repeat函数配合auto-fill关键字:
.card-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 16px;
}
.card {
background: #fff;
border: 1px solid #eee;
border-radius: 8px;
}
这行grid-template-columns的含义是:每列最小宽度240px、最大为等分剩余空间,能放几列就自动生成几列,放不下的卡片自动进入下一行。minmax(240px, 1fr)保证了卡片在窄屏下不会小于240px,在宽屏下又能均分容器宽度,一行代码就实现了完全的响应式效果,不需要写任何媒体查询。
auto-fill和auto-fit是容易混淆的两个关键字。auto-fill会尽可能多地生成列轨道,即使有些轨道暂时没有内容,轨道空间也会保留,最后一行的卡片不会被拉伸。auto-fit则会把空的轨道折叠为0,让现有卡片拉伸占满整行宽度。商品列表这类希望对齐整齐的场景推荐auto-fill,突出展示少量内容的场景可以用auto-fit。
如果项目对卡片列数有明确要求,比如大屏四列、中屏两列,直接写固定列数配合媒体查询即可:
.card-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
}
@media (max-width: 992px) {
.card-container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 576px) {
.card-container {
grid-template-columns: 1fr;
}
}
三、两种方案的对比与选择建议
两种布局方案都能实现自动换行,但细节表现不同。flex布局的优势在于灵活,卡片可以通过flex属性控制是否拉伸,个别卡片可以脱离整体排列单独调整,适合需要不规则排版的场景。它的短板是最后一行的对齐问题:flex-wrap换行后,最后一行剩余卡片如果使用了flex:1会被拉伸,如果不拉伸又会留白,很难做到既占满上一行宽度又保持卡片尺寸一致。
grid布局的优势是严格对齐,所有卡片在纵横两个方向都严格落在网格线上,列宽完全一致,最后一行的留白看起来很自然,不会出现拉伸变形。对于商品卡片、图片列表这类规则排列的场景,grid几乎是首选方案。
浏览器兼容性方面,flex-wrap和gap在grid中使用的写法在现代浏览器中均已全面支持,包括主流移动端浏览器,可以放心使用。唯一需要注意的是,如果项目仍需兼容旧版浏览器,gap属性在旧版flex实现中不被支持,此时需要退回使用margin加负值外边距的传统方案。
总结一下选择思路:卡片宽度固定、希望一行尽量多放,用flex加wrap;卡片等宽自适应、要求列严格对齐,用grid加auto-fill;需要明确的分列数断点控制,用grid加媒体查询。掌握这几个写法,卡片自动换行布局基本不会再成为难题。