需显式为父容器设置 container-type: inline-size(或 size)才能启用容器查询,否则 @container 规则静默失效;它监听父容器实际渲染尺寸,非视口,且仅作用于直接父级块级元素。

怎么写一个能监听父容器宽度的容器查询
直接给父容器加 container-type: inline-size,它就变成可被查询的“响应式容器”了。注意不是所有元素默认都支持——必须显式声明,否则 @container 规则完全不生效,连报错都不会有,这是最常踩的静默失败点。
-
container-type只接受inline-size(监听宽度)或size(宽高都监听),别写成width或max-width,那会直接被浏览器忽略 - 如果想在多个同级容器中区分查询目标,可以加
container-name: card,然后用@container card (min-width: 400px)精确匹配——但命名非必需,多数场景用不到 - 容器必须是块级上下文(比如
div、section),span这类内联元素即使加了也不会生效
@container 和 @media 的关键区别在哪
@media 看的是整个视口,@container 看的是父容器的实际渲染尺寸——这意味着拖拽调整侧边栏宽度、折叠/展开面板、甚至 JS 动态插入内容后重排,只要父容器尺寸变了,子元素样式就能实时响应;而 @media 在这些场景下完全无感。
- 典型误用:把卡片组件塞进一个
width: 300px的 flex 项目里,却还在用@media (max-width: 400px)控制布局——此时视口可能很宽,但卡片实际可用空间只有 300px,@media完全失效 - 性能上更轻量:浏览器只对声明了
container-type的元素做尺寸监听,不像@media那样要全局监听视口变化 - 兼容性截至 2026 年 3 月已覆盖 Chrome 105+、Firefox 110+、Safari 16.4+,Edge 同 Chromium 版本;IE 和旧版 Safari 不支持,且无法优雅降级——得搭配
@supports (container-type: inline-size)做条件包裹
为什么卡片在不同区域自动适配失败
大概率是容器链断了:从目标元素往上找,第一个没设 container-type 的祖先,就是查询作用域的终点。CSS 容器查询不继承、不冒泡,只认直接父容器。
- 常见结构陷阱:
<div class="sidebar"><div class="card-container"><div class="card">...</div></div></div>—— 如果只给.card-container加了container-type,那没问题;但如果误加在.sidebar上,.card就查不到 - Flex/Grid 容器本身不能直接当查询容器(除非显式声明
container-type),它的子项尺寸由布局算法决定,不是自然流式尺寸,容易导致查询值和预期不符 - 不要在
display: contents元素上设container-type,它没有渲染盒,浏览器无法获取尺寸
如何安全地和 CSS 变量配合使用
可以,但变量必须定义在容器查询规则内部,或者用 :host 类似逻辑——外部定义的全局变量(如 :root 里的)不会随容器查询触发重计算。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
@container (min-width: 500px) { .card { --gap: 1.5rem; padding: var(--gap); } } - 错误写法:在
:root里定义--gap,再指望@container修改它——这只会让变量值“卡住”,后续查询失效 - 如果要用 JS 动态改容器尺寸(比如 resize observer),记得触发重排后,浏览器会自动重新评估
@container规则,无需手动刷新样式










