返回博客

Wordpress建站

CSS 容器查询与媒体查询的区别:完整对比指南

2026-07-18

阅读约:15分钟

响应式设计是现代 Web 开发的基石。长期以来,媒体查询(Media Queries) 是实现响应式布局的唯一工具。但随着组件化开发的普及,CSS 容器查询(Container Queries)的出现为响应式设计带来了全新的思路。本文将从核心概念、语法差异、作用域、使用场景等多个维度,全面对比容器查询与媒体查询的区别。

什么是媒体查询?

媒体查询(@media)是 CSS 中最经典的响应式技术,通过检测视口(viewport)的尺寸、设备类型、分辨率等条件来应用不同的样式。

/* 当视口宽度小于 768px 时生效 */
@media (max-width: 768px) {
  .card {
    flex-direction: column;
    padding: 1rem;
  }
}

媒体查询响应的是整个浏览器窗口的变化,而非单个元素所在容器的变化。

什么是容器查询?

容器查询(@container)是 CSS 较新的特性,它允许根据父容器的尺寸而非视口尺寸来应用样式。这意味着组件可以根据自身所在的容器空间来调整布局。

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

/* 当容器宽度小于 400px 时生效 */
@container card-container (max-width: 400px) {
  .card {
    flex-direction: column;
    padding: 1rem;
  }
}

核心区别对比

1. 检测目标不同

维度媒体查询 @media容器查询 @container
检测对象视口(viewport)父容器(container)
作用范围全局组件级
响应粒度页面级元素级

媒体查询始终以浏览器视口为参照,而容器查询以被声明的祖先容器为参照。这是两者最本质的区别。

2. 组件复用性

媒体查询的局限:同一个卡片组件放在页面侧边栏(窄区域)和主内容区(宽区域)时,无法根据所在区域的宽度自动调整布局。你只能针对视口宽度写死样式,导致组件在不同位置可能显示不理想。

容器查询的优势:卡片组件只需要声明自己的容器查询规则,无论被放在侧边栏还是主内容区,都能根据实际可用空间自动适配。这极大提升了组件的可复用性。

<!-- 同一个组件,放在不同宽度的容器中,自动适配 -->
<aside style="width: 300px">
  <div class="card-wrapper">
    <div class="card">...</div>
  </div>
</aside>

<main style="width: 900px">
  <div class="card-wrapper">
    <div class="card">...</div>
  </div>
</main>

3. 语法结构

媒体查询直接使用 @media 关键字,不需要额外声明:

@media (min-width: 768px) { /* ... */ }

容器查询需要两步——先声明容器,再编写查询规则:

/* 第一步:声明容器 */
.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}

/* 第二步:查询容器 */
@container sidebar (min-width: 400px) { /* ... */ }

4. 支持的查询条件

  • 媒体查询:支持宽度、高度、设备类型(screen/print)、分辨率(dpi)、颜色能力、悬停能力(hover)、 prefers-color-scheme 等。
  • 容器查询:目前主要支持尺寸查询(inline-sizeblock-size)和样式查询(style()),条件类型相对有限,但正在扩展中。

5. 性能考量

  • 媒体查询:浏览器在视口尺寸变化时(如窗口缩放、设备旋转)重新计算匹配规则,性能开销较小且已被高度优化。
  • 容器查询:需要浏览器追踪容器尺寸变化,在某些复杂布局中可能引入额外的布局计算。但在现代浏览器中,性能差异通常可以忽略。

实际场景选择指南

适合使用媒体查询的场景

  • 页面整体布局切换(如单栏变多栏)
  • 针对打印样式(@media print
  • 针对设备特性(暗色模式、减少动画偏好)
  • 全局导航栏、页脚等非组件化的页面级元素
  • 需要检测设备类型或分辨率时
/* 全局暗色模式 */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1a1a1a;
    --fg: #f0f0f0;
  }
}

/* 打印样式 */
@media print {
  nav, footer { display: none; }
}

适合使用容器查询的场景

  • 可复用的 UI 组件(卡片、列表、表单、导航)
  • 组件库和设计系统中的通用组件
  • 组件可能被放置在页面不同位置、不同宽度的区域
  • 嵌套布局中的自适应需求
  • Widget、嵌入式内容、第三方组件集成
/* 可复用的卡片组件 */
.product-card-wrapper {
  container-type: inline-size;
}

@container (min-width: 500px) {
  .product-card {
    display: grid;
    grid-template-columns: 200px 1fr;
  }
}

@container (max-width: 499px) {
  .product-card {
    display: flex;
    flex-direction: column;
  }
}

两者可以共存

容器查询并不是要取代媒体查询,而是互补关系。在实际项目中,最佳实践是:

  • 媒体查询 处理页面级响应(整体布局、设备特性、用户偏好)
  • 容器查询 处理组件级响应(组件内部布局自适应)
/* 页面级:媒体查询 */
@media (min-width: 1024px) {
  .page-layout {
    display: grid;
    grid-template-columns: 300px 1fr;
  }
}

/* 组件级:容器查询 */
.sidebar-widget {
  container-type: inline-size;
}

@container (max-width: 280px) {
  .widget-title {
    font-size: 0.875rem;
  }
}

两者可以共存

  • 媒体查询:所有主流浏览器全面支持,包括 IE9+。
  • 容器查询:Chrome 105+、Firefox 110+、Safari 16+ 均已支持。对于需要兼容旧浏览器的项目,可配合 @supports 做渐进增强。
/* 渐进增强方案 */
.card-wrapper {
  /* 默认样式(移动优先) */
  display: flex;
  flex-direction: column;
}

@supports (container-type: inline-size) {
  .card-wrapper {
    container-type: inline-size;
  }

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

总结

对比项媒体查询 @media容器查询 @container
检测对象视口容器
粒度页面级组件级
组件复用较弱极强
语法复杂度简单需声明容器
查询条件丰富逐步扩展中
兼容性极广现代浏览器
最佳场景全局布局、设备特性可复用组件

容器查询代表了 CSS 响应式设计从"页面驱动"到"组件驱动"的演进。理解两者的区别和适用场景,能帮助你在项目中做出更合理的技术选择,构建出真正灵活、可复用的响应式组件。

标签:

响应式设计 媒体查询 容器查询 自适应布局