@container 规则需父容器显式声明 container-type: inline-size 才生效,否则静默失效;仅作用于直接后代,不支持修改容器自身样式;优先使用 inline-size 而非 size 以兼顾性能与兼容性。

container-type 必须显式声明,否则 @container 静默失效
你写了 @container (min-width: 400px) { ... } 却没生效?大概率是漏了父容器的 container-type: inline-size。浏览器不会自动把任意元素当作容器——它必须被“激活”。container-type: normal(默认值)或未声明时,@container 规则直接被忽略,控制台也不报错,极难排查。
常见错误组合:
-
display: inline元素上设container-type:无效,需改用display: block或flow-root - 父容器是
display: contents或display: none:无布局盒,无法测量尺寸 - 同一元素写了两个
container-type声明:浏览器只认最后一个 - 用
container: name / size简写但拼错语法(如漏斜杠):整个声明被丢弃
@container 作用域仅限直接后代,不能选容器自身
@container 规则里的选择器只能匹配该容器内部的后代元素,不能用于容器自己。比如 .card { container-type: inline-size; },你不能在 @container 里写 .card { display: flex; }——这不会生效。
正确写法是作用于子元素:
立即学习“前端免费学习笔记(深入)”;
@container (min-width: 400px) { .card > h3 { font-size: 1.25rem; } }@container (max-width: 300px) { .card .actions { flex-direction: column; } }- 若需影响容器自身样式,得靠外部类名或 JS 配合,
@container不支持
另外,命名容器(container-name: card)能避免多层嵌套时规则冲突,但匿名查询(不写 name)更轻量,适合单组件场景。
inline-size 是首选类型,size 开销大且兼容性稍弱
绝大多数响应式需求只关心宽度变化,用 container-type: inline-size 就够了。它只监听内联方向(通常是 width),性能好、兼容稳(Chrome 105+ / Firefox 110+ / Safari 16+ / Edge 105+ 已全支持)。
而 container-type: size 同时监听宽高,会触发更频繁的重排计算,且要求容器有明确尺寸(比如设置了 width 或 inline-size)。块级方向(block-size,即高度)支持度更低——Safari 直到 17.4 才稳定,Chrome 117+ 才完善。
别为了“看起来更完整”而滥用 size。除非你真需要根据卡片高度动态调整字体行高或折叠内容,否则坚持 inline-size。
和 @media 混用时,职责要分明
@media 和 @container 不是互斥关系,而是分工协作:
-
@media控制页面级结构:导航栏是否收起、全局字体缩放、主栅格列数 -
@container控制组件级细节:单张卡片内图片比例、价格按钮组堆叠/横排、统计图表是否显示图例
一个典型仪表盘中:@media (max-width: 768px) 把整个面板切为单列;而每个 .stat-card 内部用 @container (max-width: 250px) 自动把数字字号从 3rem 缩到 1.2rem,和视口无关——哪怕用户把浏览器拉到 2000px 宽,只要那个卡片被拖进窄侧边栏,它就立刻变小。
真正容易被忽略的是:容器查询的断点值(比如 400px)不是凭空定的,它应该来自你组件设计系统中定义的“最小可用宽度”,而不是照搬媒体查询的 768px 或 1024px。这个数字得实测——在真实嵌入场景下,组件开始挤压变形的那个临界点,才是它的容器断点。


















