CSS 实现响应式卡片的三种方法(附代码)

做卡片布局是前端最常见的需求之一。刚开始学的时候我只会写死宽度, 结果在手机上直接溢出。后来陆续试了三种方式,这里把思路和代码都整理一下。

方法一:flex + flex-wrap

最直观的一种。给容器设置 display:flex 和 flex-wrap:wrap, 每个卡片给一个 flex 基准宽度,放不下就自动换行。

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 280px;
}

这里 flex: 1 1 280px 的意思是:基准宽度 280px,可以放大也可以缩小。 容器变宽时卡片自动撑开,变窄时自动换行。

小提示:用 gap 代替 margin 处理间距,不用再纠结最后一行多出来的边距问题。

方法二:grid + auto-fill

我个人最推荐的一种。一行代码就能实现「列数随宽度自动变化」的效果。

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
}

minmax(280px, 1fr) 表示每列最小 280px、最大占满剩余空间, auto-fill 让浏览器自己决定一行放几列。窗口一缩放,列数就跟着变。

auto-fill 和 auto-fit 的区别

  • auto-fill:列数按容器宽度算,即使卡片少也会留出空列
  • auto-fit:卡片少的时候会把空列收起来,让卡片撑满整行

一般用 auto-fill 就够,想让卡片在数量少时铺满整行就换 auto-fit。

方法三:媒体查询手动控制

最传统的方式,兼容性最好,但要写的代码多。适合需要精确控制每个断点布局的场景。

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

@media (max-width: 900px) {
  .cards { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 600px) {
  .cards { grid-template-columns: 1fr; }
}

三种方式怎么选

  • 追求省事:选 grid + auto-fill,一行搞定
  • 卡片高度不一致:flex 更灵活,可以配合 align-items 调整
  • 需要精确断点:媒体查询,控制力最强

我现在基本都用第二种,遇到特殊需求再叠加媒体查询微调。 如果你也在学 CSS,建议三种都动手写一遍,感受一下差别。