容器查询通过container-type: inline-size监听父容器内容宽度,解决媒体查询无法应对组件局部尺寸变化的问题,需显式声明且注意兼容性与单位限制。

因为容器查询监听的是组件父容器的内联尺寸,不是视口宽度——这正好匹配移动端中“同一组件被塞进不同宽度区域”的真实场景。
容器查询解决的是媒体查询根本处理不了的问题
你在折叠屏上打开一个仪表盘,视口从 300px 突然变成 1200px,但侧边栏里的 .card 容器始终只有 320px 宽。这时候 @media (min-width: 768px) 会强制它按桌面样式渲染,结果图标溢出、文字换行错乱。而 @container (min-width: 320px) 查的就是它自己那 320px 的可用宽度,自然能正确触发单列布局。
常见错误现象:写了 @container 却完全没反应,控制台安静,样式也不变——90% 是漏了 container-type: inline-size,浏览器直接忽略整条规则。
- 媒体查询只看
window.innerWidth,对组件实际空间毫无感知 - 微前端子应用注入到主框架某区块时,根本不知道主应用的视口断点逻辑
- 同一页面多个动态区域(如导航收缩 + 内容拉伸)无法用单个视口断点描述
必须显式声明 container-type 才能生效
浏览器默认不把任何元素当容器,@container 不是开箱即用的功能。你得手动告诉它:“这个父元素是可查询的”。漏掉这一步,所有 @container 规则都会静默失效,且不报错。
立即学习“前端免费学习笔记(深入)”;
推荐写法:container-type: inline-size(只监听宽度,性能友好、兼容性好);避免用 container-type: size,它同时监听宽高,触发更频繁,Safari 对 height 查询支持还不稳。
- 不能加在
display: contents或position: absolute的父元素上——它们不产生块格式化上下文,属性会被浏览器静默忽略 - 父容器必须有可计算宽度:比如设置了
width、max-width,或处于flex/grid子项中并受约束;纯width: auto的div不会触发查询 - Flex/Grid 父容器上直接设
container-type几乎总是失效,得在外层加一层wrapper并把container-type加在 wrapper 上
@container 断点单位和计算逻辑和 @media 完全不同
@container 的 min-width: 320px 指的是容器 content box 的可用宽度 ≥ 320px,不是 CSS 声明的 width 值,也不是 offsetWidth。它受 padding、border、box-sizing 影响。
例如容器设了 padding: 16px 和 box-sizing: border-box,那要让 content box 刚好 320px,你得写 width: 352px(320 + 16×2)。
- 只支持
px、vw(但这里的vw是容器自身宽度的 1%,极易误解)、%(需父容器宽度确定),建议统一用px - 不支持
em、rem作断点值 -
gap不计入 inline-size 计算,但padding和border会计入
Safari 16.4 的命名容器 bug 很容易踩坑
如果你写 .card { container: card / inline-size; },再用 @container card (min-width: 400px),在 Safari 16.4 中可能完全不触发——尤其是动态插入或 SSR hydration 后。这不是配置问题,是解析不稳定。
实操建议:线上项目优先用匿名写法:.card-wrapper { container-type: inline-size; } + @container (min-width: 320px),再配合类名选择器兜底,比如 @container (min-width: 320px) { .card-wrapper .card { ... } }。
另外,@container 和 @media 必须分层协作,不能混职责:前者管组件内部(图文横排/竖排、图标显隐),后者管全局(整页列数切换、导航栏折叠)。混着写没问题,但一旦让 @container 去响应视口变化,就失去了组件独立性的意义。


















