多年来,前端工程师一直依赖媒体查询(Media Queries)来构建响应式布局。但媒体查询有一个根本性的局限:它只能感知视口(viewport)的尺寸,而无法感知组件自身容器的尺寸。CSS 容器查询(Container Queries)的推出,彻底改变了这一局面。

想象这样一个场景:同一个卡片组件,在主页的宽幅区域中展示为横向布局,在侧边栏的窄栏中展示为纵向布局。使用媒体查询时,你只能根据整个视口的宽度来做判断,无法让组件感知自己所处的容器尺寸——这导致了大量变通方案和冗余代码。

核心语法

容器查询的使用分为两步。首先,定义容器:

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

然后,针对该容器编写查询规则:

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

这样,.card 的布局就会根据 .card-wrapper 的宽度来调整,而不是根据整个视口的宽度。

容器查询 vs 媒体查询

两者的核心区别在于参考系:媒体查询以浏览器窗口为参考,容器查询以组件的直接容器为参考。这使得容器查询在组件化架构中格外强大——每个组件可以独立响应自己的容器空间,而无需关心页面的整体布局。

一个典型的例子是仪表盘布局。同一个面板组件可能出现在三栏布局的中栏(宽度约 400px),也可能出现在展开的全宽视图中(宽度约 1200px)。容器查询让组件能够自适应这些不同的上下文,而无需通过 props 或额外的 CSS 类来控制。

实际应用场景

场景媒体查询方案容器查询方案
可复用的卡片组件需要父级传递 className 控制尺寸组件自行感知容器宽度
仪表盘面板每个面板根据视口统一调整每个面板独立响应自身空间
侧边栏 widget难以处理嵌套布局自动适配嵌套容器
弹出层/对话框视口查询不够精细精确感知弹出层尺寸

迁移建议

对于现有项目,不需要一次性重写所有响应式代码。一个渐进式迁移策略如下:

容器查询不是要取代媒体查询,而是填补了媒体查询无法覆盖的空白。在组件化开发日益普及的今天,它是 CSS 响应式工具箱中一个迟到但关键的补充。