全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-16 8 分钟 ✍️ juanwangdev

容器查询实战案例:响应式卡片布局

通过卡片组件案例,演示容器查询从基础到完整的响应式设计实现。

案例场景

同一卡片组件在不同宽度容器中自适应:

  • 紧凑容器:纵向堆叠布局
  • 标准容器:图文并排布局
  • 宽松容器:多列展示布局

基础实现

HTML结构

HTML
<div class="card-container">
  <article class="card">
    <div class="card__media">
      <img class="card__image" src="photo.jpg" alt="">
    </div>
    <div class="card__content">
      <h3 class="card__title">文章标题</h3>
      <p class="card__excerpt">文章摘要内容...</p>
      <div class="card__meta">
        <span class="card__author">作者名</span>
        <span class="card__date">2026-05-16</span>
      </div>
      <button class="card__action">阅读更多</button>
    </div>
  </article>
</div>

基础样式

CSS
/* 声明容器 */
.card-container {
  container-type: inline-size;
  container-name: card;
}

/* 卡片基础样式 */
.card {
  background: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.card__image {
  width: 100%;
  height: auto;
  object-fit: cover;
}

.card__title {
  font-size: 18px;
  font-weight: 600;
  margin: 0;
}

.card__excerpt {
  font-size: 14px;
  color: #666;
  margin: 8px 0;
}

.card__meta {
  display: flex;
  gap: 12px;
  font-size: 12px;
  color: #999;
}

.card__action {
  margin-top: 12px;
  padding: 8px 16px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

响应式布局切换

紧凑布局(< 300px)

CSS
/* 默认紧凑布局 */
.card {
  display: block;
}

.card__media {
  /* 图片全宽 */
}

.card__content {
  padding: 12px;
}

.card__title {
  font-size: 16px;
}

.card__action {
  width: 100%;
}

标准布局(300px - 500px)

CSS
@container card (min-width: 300px) {
  .card {
    display: flex;
    gap: 16px;
  }

  .card__media {
    flex-shrink: 0;
    width: 120px;
  }

  .card__image {
    width: 120px;
    height: 120px;
    object-fit: cover;
  }

  .card__content {
    padding: 16px;
    flex: 1;
  }

  .card__title {
    font-size: 18px;
  }

  .card__action {
    width: auto;
  }
}

宽松布局(> 500px)

CSS
@container card (min-width: 500px) {
  .card {
    flex-direction: row;
    gap: 24px;
  }

  .card__media {
    width: 200px;
  }

  .card__image {
    width: 200px;
    height: 150px;
  }

  .card__content {
    padding: 24px;
    display: flex;
    flex-direction: column;
  }

  .card__title {
    font-size: 24px;
  }

  .card__excerpt {
    font-size: 16px;
  }

  .card__meta {
    margin-top: auto;
  }
}

使用容器单位

相对字体大小

CSS
.card__title {
  /* 基于容器宽度的相对字体 */
  font-size: calc(14px + 2cqw);
}

/* 容器300px → 14+6=20px */
/* 容器500px → 14+10=24px */

相对间距

CSS
.card__content {
  padding: 2cqw 3cqw;
}

/* 容器300px → padding: 6px 9px */
/* 容器500px → padding: 10px 15px */

相对图片尺寸

CSS
@container card (min-width: 300px) {
  .card__media {
    width: 30cqw;
  }

  .card__image {
    width: 30cqw;
    height: 30cqw;
  }
}

多容器场景

HTML
<!-- 主内容区 -->
<main class="main-content">
  <div class="card-container">
    <article class="card">...</article>
  </div>
</main>

<!-- 侧边栏 -->
<aside class="sidebar">
  <div class="card-container">
    <article class="card">...</article>
  </div>
</aside>

<!-- 相关推荐区 -->
<section class="related-section">
  <div class="card-container">
    <article class="card">...</article>
  </div>
</section>
CSS
/* 不同容器宽度 */
.main-content {
  width: 800px;
}

.sidebar {
  width: 250px;
}

.related-section {
  width: 400px;
}

/* 同一卡片组件在不同容器中自适应 */
/* 主内容区:宽松布局 */
/* 侧边栏:紧凑布局 */
/* 相关区:标准布局 */

卡片网格

HTML
<div class="grid-container">
  <div class="card-container">
    <article class="card">...</article>
  </div>
  <div class="card-container">
    <article class="card">...</article>
  </div>
  <div class="card-container">
    <article class="card">...</article>
  </div>
</div>
CSS
.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}

.card-container {
  container-type: inline-size;
}

/* 网格项宽度动态变化,卡片自动适应 */

悬停状态增强

CSS
@container card (min-width: 300px) {
  .card {
    transition: transform 0.2s, box-shadow 0.2s;
  }

  .card:hover {
    transform: translateY(-4px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  }
}

/* 紧凑布局禁用悬停效果 */
@container card (max-width: 299px) {
  .card:hover {
    /* 无悬停效果 */
  }
}

深色模式适配

CSS
@container card (min-width: 300px) {
  .card {
    background: white;
    color: #333;
  }
}

/* 媒体查询控制深色模式 */
@media (prefers-color-scheme: dark) {
  @container card (min-width: 300px) {
    .card {
      background: #1a1a1a;
      color: #e0e0e0;
    }

    .card__excerpt {
      color: #aaa;
    }
  }
}

完整代码整合

CSS
/* 容器声明 */
.card-container {
  container: card / inline-size;
}

/* 紧凑布局(默认) */
.card {
  display: block;
  background: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.card__content {
  padding: 12px;
}

.card__title {
  font-size: calc(14px + 2cqw);
  font-weight: 600;
}

.card__action {
  width: 100%;
  margin-top: 12px;
}

/* 标准布局 */
@container card (min-width: 300px) {
  .card {
    display: flex;
    gap: 16px;
  }

  .card__media {
    flex-shrink: 0;
    width: 120px;
  }

  .card__image {
    width: 120px;
    height: 120px;
  }

  .card__content {
    padding: 16px;
    flex: 1;
  }

  .card__action {
    width: auto;
  }
}

/* 宽松布局 */
@container card (min-width: 500px) {
  .card {
    gap: 24px;
  }

  .card__media {
    width: 200px;
  }

  .card__image {
    width: 200px;
    height: 150px;
  }

  .card__content {
    padding: 24px;
  }
}

要点总结

  1. 容器声明:container-type: inline-size启用查询
  2. 多断点布局:@container (min-width: Xpx)分级控制
  3. 容器单位:cqw实现相对尺寸
  4. 同一组件在不同容器自动适配
  5. 结合媒体查询处理深色模式等全局状态

📝 发现内容有误?点击此处直接编辑

← 上一篇 容器查询基础概念
下一篇 → 容器查询的浏览器兼容性与polyfill
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库