唯一安全的降级入口是@supports not (container-type: inline-size),需直接包裹降级样式,不可嵌套于@media或@container内,且降级应采用大颗粒度布局调整而非精确模拟容器查询。
直接用 @supports not (container-type: inline-size) 包裹降级样式,别写 JS 检测、别加 polyfill、也别在 @media 里嵌套它。这个检测在 CSS 解析阶段就生效,SSR 下也能正确跳过规则块;其他写法如 @supports (@container) 或 @supports (container: inline-size) 全部解析失败,整条规则静默丢弃。
把降级逻辑塞进 @container 规则内部是无效的——CSS 不允许媒体查询与容器查询嵌套混写,浏览器会直接忽略整块。同时,@supports not 块也不能写在 @media 里面,否则旧浏览器可能误执行,新浏览器又重复应用,造成样式打架。
@supports not (container-type: inline-size) { @media (min-width: 768px) { .card { display: flex; } } }
@container (min-width: 400px) { @supports not (...) { ... } }(语法非法)@media (min-width: 768px) { @supports not (...) { ... } }(旧浏览器可能执行,新浏览器仍匹配 @container)不要试图用 @media 精确还原 @container 的局部响应逻辑——它做不到。真正可行的是做「大颗粒度 fallback」:比如 @container (max-width: 400px) 控制卡片内文字换行,降级时就用 @media (max-width: 768px) 把整个卡片区域切为单列布局,而不是硬凑一个视口宽度去匹配容器宽度。
@container 负责组件内微调(头像尺寸、按钮文字缩放),@media 负责页面级结构切换(grid → flex → stack)container-type: size 降级——它需同时监听宽高,@media 根本无法等效,且会强制触发 layout containment,拖慢渲染width: max-content),% 单位在降级中极易失效,统一用 px 更可控线上项目若需兼容 Safari 16.4,别依赖 container-name 做关键降级分支。该版本对命名容器的解析不稳定,@container sidebar (min-width: 320px) 可能完全不触发。此时应改用匿名容器 + @supports not 直接包裹等效 @media,或干脆放弃命名,靠 DOM 结构层级做隔离。
真正难处理的不是“怎么写降级”,而是“哪些地方根本不能降级”:比如一个卡片组件被嵌入到第三方 iframe 或 Shadow DOM 中,它的容器宽度和视口完全无关,此时任何 @media 都失效,只能靠服务端预判或放弃响应式。这种边界场景,@supports not 能兜住样式不崩,但逻辑适配得另想办法。