你以为响应式就是看屏幕宽度?今天 CSS 把这件事彻底变成看容器脸色
同一个卡片组件,放在主内容区是横排,放进侧边栏还是横排——页面没变、视口没变,就因为容器宽度不同,你得给同一个组件写两份媒体查询来”兜底”。
CSS 容器查询(Container Queries)把这套逻辑彻底翻了。
问题出在哪
媒体查询的参照物是浏览器窗口。组件只知道自己身处多宽的屏幕,不知道自己实际被塞进了多窄的空间。把同一个卡片放进 300px 的侧边栏,它只认视口——视口足够宽,就一直横排,根本不管侧边栏已经把它压成了一条细缝。
传统解法是靠父组件传递断点:u003cCard narrow={isNarrow} /u003e,或者用 JavaScript 实时检测容器宽度再动态加 class。这些”兜底”方案每个项目都要写,写完还很难复用。
CSS 怎么原生解决
两步走:先给父容器声明”我是容器”,再让子元素查询父容器宽度。
“`css
/ 第一步:把父容器标记为查询目标 /
.card-wrapper {
container-type: inline-size;
container-name: card;
}
/ 第二步:子元素根据容器宽度响应 /
.card {
display: flex;
flex-direction: column; / 默认竖排 /
}
@container card (min-width: 380px) {
.card {
flex-direction: row; / 容器 ≥ 380px 自动横排 /
align-items: center;
}
}
“`
关键点:
container-type: inline-size:告诉浏览器”这个元素的行内方向尺寸变化时我要知道”,只监听宽度,不监听高度,大多数场景够用container-name:给容器起个名字,@container card精确查询这个名字对应的容器,嵌套场景不会串线container-type: size:同时监听宽高,极少见用
同一个卡片,放进侧边栏时容器宽度 u003c 380px 就自动竖排,放进主内容区 ≥ 380px 就自动横排——组件本身零修改,CSS 自己会认路。
配套单位:cqi / cqb / cqw / cqh
容器查询带来了四个专属单位,让字体、间距也能随容器缩放:
“`css
.card-title {
font-size: clamp(1rem, 4cqi, 2rem); / 随容器宽度等比缩放 /
}
“`
cqi:容器行内方向尺寸的 1%,即宽度的 1%cqb:容器块级方向尺寸的 1%,即高度的 1%cqw / cqh:分别等于 cqi / cqb,别名
这个能力靠媒体查询根本做不到——视口宽度和组件可用宽度是两回事。
三步迁移路径
- 找兜底 JS:项目里搜
offsetWidth、getBoundingClientRect、ResizeObserver,这些八成是给组件测宽度用的——可以开始考虑用容器查询替代 - 从卡片开始:选一个复用场景最多的组件,加上
container-type: inline-size,把原来的媒体查询断点换成@container规则 - 渐进增强:用
@supports (container-type: inline-size)包裹新写法,旧浏览器继续用媒体查询的兜底方案,不破坏任何功能
真实迁移数据
Mintec 博客记录了一个教育平台的设计系统迁移案例:47 个组件、8 个媒体查询断点、6 人团队。换成容器查询后,样式重算性能降低 34%(浏览器只重算当前容器内样式,不再触发全文档重排),CSS 代码量减少 22%,删除了约 200 行”只用来检测容器宽度”的 JavaScript。
三个坑
- 容器本身不能查询自己:给一个元素加了
container-type,它自己不能用@container查询自己的尺寸——查询的是祖先容器的尺寸,需要在父级建立 containment - 嵌套容器不会互相干扰:子容器和父容器各自独立查询,不会因为外层宽度小导致内层组件也觉得自己窄——每个
@container只看自己那一层 - 旧浏览器没有兜底:主流浏览器全部支持(Chrome 105+ / Firefox 110+ / Safari 16+),2026 年全球覆盖率超过 93%,如果你的用户还有 7% 的 IE 用户,记得加
@supports渐进增强
一句话总结
媒体查询回答”屏幕有多宽”,容器查询回答”我的容器给我留了多少”。这两个问题不一样,组件级别的响应式,只能靠容器查询原生解决,媒体查询做不到。
下一步
今晚翻一个你项目里复用最多的组件,找到它的父容器,加一行 container-type: inline-size,再把原来的媒体查询断点改成 @container——你马上就知道这东西有多值。
评论区
登录后可评论。