旧浏览器直接跳过@container规则,无法CSS回退,必须JS模拟;container-query-polyfill最轻量,需显式设container-name、init()调用,仅支持inline-size,存在兼容性与精度问题。

旧浏览器根本不会解析 @container 规则——不是“不生效”,而是直接跳过整条规则,连里面的条件和选择器都不进 CSS 解析器。这意味着你不能靠 CSS 自身做回退,必须用 JS 模拟或提供静态 fallback。
为什么不能写 CSS 级 polyfill?
CSS 没有运行时能力,无法监听尺寸变化、无法判断容器当前宽高、也无法动态插入匹配的样式块。所有所谓“polyfill”本质都是 JS 驱动的模拟方案,必须配合 DOM 监听 + 样式重写。
-
@container在 Chrome 105 / Firefox 119 / Safari 16.4 之前全部被忽略,且不报错 - 即使加了
@supports not (container-type: inline-size),也无法触发回退样式——因为整个@container块已被丢弃,@supports根本看不到它存在 - 别试图用
var(--container-width)或其他 CSS 变量绕过,变量无法读取真实容器尺寸
用 container-query-polyfill 是目前最轻量可行的方案
它不改写原生语法,而是提取 @container 规则,监听容器尺寸,再手动加 class 到子元素上,靠普通类选择器触发样式。
- 必须显式给容器加
container-name(如style="container-name: card;"),不支持简写的container属性 - 必须在
<link>或<style>加载完成后调用init(),否则不生效:import { init } from 'container-query-polyfill';\ninit(); - 只支持
container-type: inline-size,不支持size或block-size - 内部已做 32ms 节流,但大量嵌套容器仍可能卡顿,建议对非关键容器延迟初始化
自己写 fallback 时别踩 ResizeObserver 兼容性坑
很多团队误以为加了 resize-observer-polyfill 就万事大吉,其实 Edge 16–18 和部分安卓 WebView 有严重 bug:嵌套容器返回 contentRect.inlineSize === 0,或回调根本不触发。
立即学习“前端免费学习笔记(深入)”;
- IE11 完全不支持
ResizeObserver,只能退到scroll+offsetWidth轮询(每 200ms check 一次),但无法响应transform: scale()类变化 - 别依赖
contentRect.inlineSize字段——旧 polyfill 返回的是width,而原生 API 在 container query 场景下应返回逻辑内联尺寸(比如 writing-mode: vertical-rl 下是高度) - 务必在真实设备上测临界点:比如
@container (min-width: 300px)在 polyfill 下可能因四舍五入变成 299.7px → 不触发
真正难的不是实现 polyfill,而是让 JS 模拟行为和原生 @container 在边界条件、节流时机、嵌套层级、writing-mode 下保持一致——这点目前没有任何方案能 100% 覆盖。


















