父容器必须显式声明 container-type: inline-size 才能使 @container 规则生效,否则整条规则静默忽略;当前唯一广泛兼容的取值是 inline-size,专为宽度响应设计。

@container 规则本身不会生效,除非父容器显式声明 container-type: inline-size——这是 90% 的失效原因,不是写法错,是漏了这一步。
父容器必须设 container-type: inline-size 才能触发查询
浏览器对 @container 是“零容忍”:没声明类型,整条规则静默忽略,DevTools 里连匹配提示都不会出现。这不是语法错误,也不报红,但等于白写。
-
container-type: inline-size是当前唯一广泛兼容的取值(Chrome 105+、Safari 16.4+、Firefox 119+),专为宽度响应设计 - 别用
container-type: size—— 它要求宽高同时满足,且需配container-name,兼容性差、实用性低 - 不能设在
body或:root上:这些节点默认不构成格式化上下文,绝大多数浏览器下无效 - 避免设在
display: inline、position: absolute、float或display: contents的元素上——它们的尺寸不可测,查询永远返回0px
@container 断点单位只认 px、%、vw,别碰 em/rem
容器查询的尺寸基准是父容器的「内容区可用宽度」(inline-size available space),不是视口,也不是根字体大小。用错单位,断点就彻底失灵。
- 最稳的是
px:例如@container (min-width: 480px),直接比 content box 宽度 -
%只在父容器有明确宽度时有效;若父容器是width: max-content,50%可能算出0px,慎用 -
em、rem、calc()、vh全部不支持——它们会退化成视口或根字体基准,完全违背容器查询本意 - 注意盒模型影响:
min-width: 400px判断的是 content box ≥ 400px;如果容器有padding: 16px且box-sizing: border-box,那它的 CSSwidth至少得是432px才能触发
命名容器(container-name)不是可选,而是协作刚需
当页面存在多个可查询容器(比如侧边栏、主卡片区、弹窗内嵌组件),不命名就会互相干扰——所有匿名 @container 规则都会匹配最近的合格祖先,极易误触发。
立即学习“前端免费学习笔记(深入)”;
- 给父容器加
container-name: sidebar,再写@container sidebar (min-width: 320px),这条规则就只对它生效 - 同一元素可有多个名字:
container-name: header, nav,对应不同用途的查询块 - 命名不区分大小写,但建议全小写+短横线,如
card-grid,避免和自定义属性冲突 - 未命名容器属于“匿名组”,多人维护时很难追溯样式来源,上线后排查成本陡增
@container 里不能直接声明 CSS 变量
@container 是条件规则,不是作用域。它本身不提供变量声明能力,也不能通过 :host 或类似机制注入变量。
- 错误写法:
@container (min-width: 500px) { --gap: 24px; }—— 这行不通,变量不会被定义 - 正确做法:用具体选择器落地,例如
@container (min-width: 500px) { .card { --card-gap: 24px; } } - 变量最终生效还依赖两点:目标元素实际用了
var(--card-gap),且该元素 DOM 路径上存在已启用container-type的祖先 - 别指望
@container像 JS 闭包一样“包裹”变量作用域——CSS 没这层抽象
真正卡住人的从来不是语法,而是让父容器“可测”:flex 子项的 min-width: auto 会锁死收缩,grid 轨道没尺寸约束时容器宽度为 0,contain 层级没配对就会泄漏干扰。这些细节一错,查询就永远等不到第一次触发。


















