使用 CSS 容器查询的现代布局

使用 CSS 容器查询的现代布局

构建响应容器而非视口的组件——@container、cqi 单位与实用模式。

2026年3月25日10 分钟阅读作者 Shehzad Asadullah

CSS 容器查询是近年来添加到 Web 平台最重要的布局能力之一。与响应视口尺寸的媒体查询不同,容器查询使组件能根据其父容器尺寸自适应。这种从页面级到组件级响应式的转变解决了设计系统中的长期难题:构建在任何上下文中都看起来正确的真正可复用组件,而无需全局断点覆盖。

CSS 容器查询根据父容器宽度调整组件布局的示意图
容器查询让组件响应其可用空间而非视口,实现真正的模块化响应式设计。

容器查询与媒体查询

媒体查询通过允许样式根据视口宽度变化革新了响应式设计。但视口宽度是单个组件可用空间的拙劣代理。侧边栏小部件、仪表板卡片和全宽主图区在视口相同时存在于不同宽度。

这种不匹配迫使开发者采用尴尬变通:

  • 从父组件传递断点 props 以覆盖子样式。
  • 使用 JavaScript ResizeObserver 根据元素宽度切换类。
  • 为不同布局上下文创建重复组件变体。
  • 依赖在布局变化时失效的 CSS grid 和 flexbox 技巧。

容器查询消除这些变通。包裹在容器上下文中的组件在其分配空间变化时自动调整内部布局 — 无论是视口调整、侧边栏切换还是网格列重排。

@container 规则

容器查询使用两个 CSS 构造:父元素上的 container-type 属性和后代样式上的 @container at 规则。父级声明自己为查询容器,子级根据容器尺寸编写条件样式。

/* Parent establishes a query container */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1rem;
}

/* Each card container enables size queries for its children */
.product-card {
  container-type: inline-size;
  container-name: card;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

/* Child styles respond to container width, not viewport */
@container card (min-width: 400px) {
  .product-card .card-body {
    display: flex;
    gap: 1rem;
  }

  .product-card .card-image {
    width: 40%;
    flex-shrink: 0;
  }

  .product-card .card-details {
    flex: 1;
  }
}

@container card (max-width: 399px) {
  .product-card .card-image {
    width: 100%;
    aspect-ratio: 16 / 9;
  }
}

container-type 属性接受 inline-size(水平书写模式下的宽度)、size(宽高)或 normal(非容器)。大多数布局用例只需 inline-size,也是最高效的选项,因为浏览器只跟踪一个维度。

容器查询单位

容器查询引入了引用查询容器尺寸而非视口的新 CSS 长度单位。这些单位实现随组件尺寸缩放的流体排版和间距。

  • cqw — 查询容器宽度的 1%。
  • cqh — 查询容器高度的 1%。
  • cqi — 查询容器行内尺寸的 1%。
  • cqb — 查询容器块尺寸的 1%。
  • cqmin — cqi 和 cqb 中较小者。
  • cqmax — cqi 和 cqb 中较大者。
.stat-widget {
  container-type: inline-size;
}

.stat-widget .value {
  /* Font size scales with container width */
  font-size: clamp(1.5rem, 5cqi, 3rem);
}

.stat-widget .label {
  font-size: clamp(0.75rem, 2.5cqi, 1rem);
}

将容器查询单位与 clamp() 结合,在组件内创建平滑缩放的排版,无需硬断点跳跃。窄侧边栏中的统计小部件渲染较小文字,宽仪表板面板中的同一组件渲染较大文字 — 自动完成,无需 props 或 JavaScript。

样式查询与容器查询特性

除尺寸查询外,CSS 容器查询规范还包括响应容器计算样式值的样式查询。你可查询自定义属性值,使组件感知父级主题上下文。

.theme-container {
  container-type: inline-size;
  --variant: default;
}

.theme-container[data-variant="compact"] {
  --variant: compact;
}

@container style(--variant: compact) {
  .nested-component {
    padding: 0.5rem;
    font-size: 0.875rem;
  }
}

样式查询在设计系统中特别强大:容器设置语义令牌,子组件相应调整密度、间距和排版。此模式取代通过组件树钻取变体标志。

无需媒体查询构建响应式组件

容器查询的实用目标是组件在任何放置处都正确工作。考虑用于全页视图、模态对话框和仪表板小部件的数据表组件。仅使用媒体查询时,三个实例共享绑定视口宽度的相同断点逻辑,至少在一个上下文中产生破损布局。

使用容器查询,表格组件定义自己的响应式行为:

  • 容器宽度超过 600px — 以标准表格布局显示所有列。
  • 400px 至 600px — 隐藏低优先级列,减少内边距。
  • 低于 400px — 切换到带标签-值对的堆叠卡片布局。
.data-table-wrapper {
  container-type: inline-size;
  container-name: table;
  overflow-x: auto;
}

@container table (max-width: 399px) {
  .data-table thead {
    display: none;
  }

  .data-table tr {
    display: block;
    margin-bottom: 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 0.75rem;
  }

  .data-table td {
    display: flex;
    justify-content: space-between;
    padding: 0.25rem 0;
  }

  .data-table td::before {
    content: attr(data-label);
    font-weight: 600;
  }
}

此组件对其父布局零知识。放入任何容器即可自适应。这就是容器查询兑现的承诺。

框架集成

现代 CSS 框架原生拥抱容器查询。Tailwind CSS v4 包含容器查询变体 — 在断点前加 @ 前缀即可根据容器尺寸应用样式。Styled-components 等 CSS-in-JS 库在模板字面量中支持 @container at 规则,无需额外配置。

在 React 组件库中,在组件根建立容器上下文,让内部元素使用容器查询做布局决策。记录哪些组件具有容器感知,以便消费者知道避免将其约束在最小功能宽度以下。

浏览器支持与渐进增强

截至 2026 年,容器查询在 Chrome、Firefox、Safari 和 Edge 中获得广泛支持。对于少数不支持的传统浏览器,应用渐进增强:为最常见容器尺寸设计默认样式,再为支持的浏览器添加容器查询覆盖。

使用 @supports 规则检测容器查询支持,必要时提供媒体查询回退:

/* Fallback for browsers without container query support */
@media (max-width: 600px) {
  .product-card .card-body {
    flex-direction: column;
  }
}

/* Enhanced layout for supporting browsers */
@supports (container-type: inline-size) {
  @container card (max-width: 399px) {
    .product-card .card-body {
      flex-direction: column;
    }
  }
}

容器查询标志着 CSS 作为组件驱动设计语言的成熟。通过将响应式逻辑从页面级转移到组件级,它们使设计系统中每个组件真正自包含、自适应且可复用。在下一个项目中拥抱容器查询,体验响应式设计本应如此工作的方式。

喜欢这篇文章吗?

有项目或想法吗?我很乐意听你聊聊。

联系我