@container 无反应的主因是父元素未声明 container-type;必须显式设置 inline-size 或 size,且需避免 flex/grid 容器直接设、display: contents/none 元素套用、使用 vw/% 单位、忽略 container-name 命名冲突及 overflow/flex 等限制测量的属性。

为什么写了 @container 却没反应
最常见的情况是:只写了查询规则,但父元素根本没申领“容器资格”。浏览器默认不把任何元素当作可查询容器——@container 不是写完就生效的语法糖,它依赖显式声明。
必须在卡片外层容器上设置 container-type: inline-size(查宽度)或 container-type: size(宽高都查)。漏掉这句,整个 @container 规则会被浏览器直接忽略。
-
container-type: inline-size是绝大多数卡片场景的必需项;block-size查高度目前仅 Chrome 117+ 稳定支持,Safari/Firefox 仍受限 - 别套在
display: contents或display: none元素上——它们不生成布局盒,无法测量尺寸 - Flex/Grid 容器本身不适合直接设
container-type,因为子项尺寸由算法动态分配,inline-size常为 0;正确做法是在卡片直接父元素(如.card-wrapper)上设
@container 断点单位只能用 px、em,不能用 vw 或 %
这是和 @media 最易混淆的一点:容器查询的尺寸基准是容器自身,不是视口。所以 vw、% 这类相对视口的单位在 @container 里直接被忽略,整条规则失效。
正确写法示例:
@container card (min-width: 300px) {
.card { flex-direction: column; }
}
@container (min-width: 24em) {
.card-title { font-size: 1.125rem; }
}
- 推荐优先用
px,语义清晰、兼容性好;em可用于字体相关断点,但需注意继承链 - 不支持
clamp()、calc()等计算表达式 - 多条件用空格分隔:
(min-width: 400px) and (max-width: 600px)
命名容器 container-name 不是可选,而是防冲突刚需
匿名查询(不设 container-name)只匹配最近的、满足 container-type 的祖先。一旦组件嵌套或复用,很容易命中错误层级。
比如卡片内部有标签云,两者都设了 container-type: inline-size,又都没命名,那么 @container (min-width: 300px) 可能查的是标签云自己的宽度,而非卡片容器——结果卡片缩窄了,标签云样式却没变。
- 外层容器设
container-name: card,内层设container-name: tag-cloud - 查询时明确指定:
@container card (min-width: 300px) - 多个同类卡片并列时,名字重复会导致所有同名容器同时响应;要么用唯一值(如
card-1),要么省略名字改用匿名查询(仅限单层结构)
Flex/Grid 布局里加容器查询的典型陷阱
直接给 display: flex 或 display: grid 的父容器加 container-type,大概率会失效——它的 inline-size 往往不可靠或为 0,因为尺寸由 Flex/Grid 算法动态分配,不是静态 CSS 测量能拿到的。
正确路径是“绕一层”:
- 在 Flex/Grid 的直接子元素上设容器,比如每个
.grid-item内部再包一层<div class="card-wrapper">,并在该 div 上设 <code>container-type: inline-size - 确认父级没加
overflow: hidden、min-width: auto或flex: 1这类限制测量的属性 - 加
contain: layout style size能强化边界稳定性,尤其内容动态加载时防止查询错位
复杂点往往藏在“容器是否真正可测”这个判断上——不是写了 container-type 就万事大吉,得确保浏览器真能拿到那个宽度数值。











