创见博客
基于 Flex 布局的响应式自适应卡片布局
七崽爱吃小饼干2026/02/28阅读 1

基于 Flex 布局的响应式自适应卡片布局:在父容器不同宽度区间内,一行显示的卡片数量自动变化,同时卡片间距固定、宽度自适应填充剩余空间。这是前端开发中非常常见的需求(比如商品列表、宫格布局)。

一、核心实现思路

要实现这个效果,需要结合 Flex 布局 + CSS 媒体查询(Media Query) + calc() 计算宽度,核心逻辑:

  1. 用 Flex 容器实现卡片横向排列,flex-wrap: wrap 让卡片自动换行;
  2. 用媒体查询划分父容器宽度区间,不同区间设置一行显示的卡片数量;
  3. 用 calc() 计算每张卡片的宽度(总宽度 - 所有间距)/ 卡片数量,保证间距固定、宽度自适应;
  4. 用 gap 或 margin 控制卡片间距(推荐 gap,更简洁)。

二、完整可运行代码

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Flex 响应式卡片布局</title>
  <style>
    /* 父容器:核心 Flex 配置 */
    .card-container {
      width: 90%; /* 父容器宽度(可根据需求调整,比如100%) */
      margin: 0 auto; /* 居中 */
      display: flex;
      flex-wrap: wrap; /* 自动换行 */
      gap: 16px; /* 固定间距(水平+垂直),替代margin更方便 */
      padding: 20px 0;
      border: 1px solid #eee;
    }

    /* 卡片基础样式 */
    .card {
      /* 初始宽度(会被媒体查询覆盖,仅作兜底) */
      width: calc((100% - 16px * 1) / 2); /* 默认一行2个 */
      height: 150px;
      background: #f5f5f5;
      border-radius: 8px;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 18px;
    }

    /* 媒体查询:按父容器宽度划分区间,调整一行卡片数量 */
    /* 区间1:父容器宽度 ≥ 1200px → 一行4个 */
    @media (min-width: 1200px) {
      .card {
        width: calc((100% - 16px * 3) / 4); 
        /* 计算逻辑:总宽度 - (间距 * (卡片数-1)) / 卡片数 */
      }
    }

    /* 区间2:父容器宽度 ≥ 768px 且 < 1200px → 一行3个 */
    @media (min-width: 768px) and (max-width: 1199px) {
      .card {
        width: calc((100% - 16px * 2) / 3);
      }
    }

    /* 区间3:父容器宽度 ≥ 480px 且 < 768px → 一行2个 */
    @media (min-width: 480px) and (max-width: 767px) {
      .card {
        width: calc((100% - 16px * 1) / 2);
      }
    }

    /* 区间4:父容器宽度 < 480px → 一行1个 */
    @media (max-width: 479px) {
      .card {
        width: 100%; /* 无间距,宽度100% */
      }
    }
  </style>
</head>
<body>
  <div class="card-container">
    <div class="card">卡片1</div>
    <div class="card">卡片2</div>
    <div class="card">卡片3</div>
    <div class="card">卡片4</div>
    <div class="card">卡片5</div>
    <div class="card">卡片6</div>
  </div>
</body>
</html>

三、关键代码解释

1. 父容器核心配置

css
.card-container {
  display: flex;       /* 开启Flex布局 */
  flex-wrap: wrap;     /* 卡片超出容器宽度时自动换行 */
  gap: 16px;           /* 固定间距:水平和垂直方向都是16px,无需手动处理margin */
}
  • gap 是 Flex/Grid 布局的专属属性,直接控制项目之间的间距,比用 margin 更简洁(无需处理最后一个元素的多余 margin);
  • 如果需要兼容老旧浏览器(如 IE),可以替换为 margin 实现:
    css
    .card { margin: 0 8px 16px 8px; } /* 水平间距8px*2=16px,垂直间距16px */
    .card-container { margin: 0 -8px; } /* 抵消容器内边距 */
    

2. 卡片宽度计算(核心)

宽度计算公式:

css
width: calc((100% - 间距 * (一行卡片数 - 1)) / 一行卡片数);
  • 示例:一行4个卡片、间距16px → calc((100% - 16px*3)/4);
  • 逻辑:总宽度减去「所有卡片之间的间距总和」,再平分给每个卡片,保证间距固定、卡片宽度自适应。

3. 媒体查询区间划分

按常见的设备宽度划分区间(可根据需求自定义):

  • ≥1200px(大屏PC):一行4个;
  • 768px~1199px(平板/小屏PC):一行3个;
  • 480px~767px(大屏手机):一行2个;
  • <480px(小屏手机):一行1个。

四、优化与拓展

1. 动态卡片数量适配

如果卡片数量不固定,Flex 的 flex-wrap: wrap 会自动换行,无需额外处理,比如6个卡片在一行4个的区间里,会显示2行(4个+2个),且每行的卡片宽度一致。

2. 兼容移动端

在 <head> 里添加视口设置,保证移动端适配:

html
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">

3. 卡片最小宽度限制

如果不想让卡片缩得太窄,可以添加 min-width 限制,结合 flex 实现更灵活的适配:

css
.card {
  flex: 1 1 calc((100% - 16px * 3) / 4); /* 伸缩+基准宽度 */
  min-width: 200px; /* 最小宽度,小于该值时自动换行 */
}

这种方式无需媒体查询,也能实现“宽度足够时显示更多卡片,不足时自动换行”,适合不想固定区间的场景。

总结

  1. 核心方案:Flex(flex-wrap: wrap)+ 媒体查询 + calc() 计算宽度,实现不同区间一行显示不同卡片数,间距固定;
  2. 间距控制:优先用 gap 实现固定间距,兼容老旧浏览器则用 margin;
  3. 灵活拓展:可通过 min-width + flex 替代媒体查询,实现无区间的自适应换行。
评论
0/100