CSS 容器查询实战

以前做响应式只能看视口宽度(媒体查询),同一个组件在侧栏里和主内容区里表现一样?容器查询让组件根据父容器尺寸自适应,真正实现组件级响应式。

CSS 容器查询配图:蓝色渐变背景上嵌套容器盒子带边界轮廓,内部模块随外层容器框尺寸变化,扁平科技插画
容器查询:让组件根据父容器尺寸自适应

一、为什么需要容器查询

媒体查询(@media)只看视口宽度,不看组件实际渲染空间。同一个卡片组件放在主内容区(800px)和侧栏(300px)里,媒体查询无法区分。容器查询让组件根据父容器的宽度自动调整布局。

维度媒体查询容器查询
判断依据视口宽度父容器宽度
粒度页面级组件级
复用性组件绑定视口组件可在任意容器自适应

二、基础用法

/* 第一步:把父元素声明为容器 */
.card-container {
  container-type: inline-size;  /* 只查宽度 */
  container-name: card;          /* 命名容器 */
}

/* 第二步:在容器查询里写响应式样式 */
@container card (min-width: 400px) {
  .card {
    display: flex;
    flex-direction: row;
  }
}

@container card (max-width: 399px) {
  .card {
    display: flex;
    flex-direction: column;
  }
}
浏览器支持:容器查询在 Chrome 105+、Safari 16+、Firefox 110+ 已支持。现代浏览器全覆盖,可在生产环境使用。

三、实战:自适应卡片组件

<!-- 同一个卡片组件,放在不同宽度的容器里 -->
<div class="sidebar">
  <div class="card-container">
    <div class="card">
      <img src="cover.jpg" alt="封面">
      <div class="card-body">
        <h3>卡片标题</h3>
        <p>卡片描述文字</p>
      </div>
    </div>
  </div>
</div>

<div class="main-content">
  <div class="card-container">
    <div class="card">
      <img src="cover.jpg" alt="封面">
      <div class="card-body">
        <h3>卡片标题</h3>
        <p>卡片描述文字</p>
      </div>
    </div>
  </div>
</div>
.card-container {
  container-type: inline-size;
}

/* 窄容器:上下排列 */
@container (max-width: 299px) {
  .card { flex-direction: column; }
  .card img { width: 100%; height: 120px; object-fit: cover; }
}

/* 宽容器:左右排列 */
@container (min-width: 300px) {
  .card { flex-direction: row; }
  .card img { width: 120px; height: 120px; flex-shrink: 0; }
}

四、container-type 的三种值

/* inline-size:只查询内联轴宽度(最常用) */
.card-container { container-type: inline-size; }

/* size:查询宽和高 */
.modal-container { container-type: size; }

/* normal:不是容器,恢复默认 */
.reset { container-type: normal; }

五、配合 CSS 变量

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

/* 容器查询里修改变量 */
@container card (min-width: 600px) {
  .card {
    --title-size: 24px;
    --padding: 20px;
  }
}

.card {
  font-size: var(--title-size, 16px);
  padding: var(--padding, 12px);
}

六、容器查询单位

/* cqw:容器宽度的 1% */
.card-title {
  font-size: 5cqw;  /* 容器宽 400px 时 = 20px */
}

/* cqh:容器高度的 1% */
.card-image {
  height: 50cqh;
}

七、总结

容器查询是 CSS 响应式的下一个台阶:从"页面级响应式"进化到"组件级响应式"。核心三步:父元素设 container-type、子元素用 @container 查询、配合 cqw/cqh 单位。同一个组件在侧栏和主内容区自动适配,不用为不同位置写不同组件。