@supports 仅分流不降级,降级样式须写在外部且兼容旧浏览器;单用 @supports (display: grid) 会误放行半支持环境(如Safari 10.1),需叠加关键特性检测(如 and (grid-template-columns: 1fr))才能精准拦截。

@supports 本身不提供降级,只负责分流;降级样式必须写在它外面,且语法得是 IE 或旧 WebView 能理解的。
为什么 @supports (display: grid) 单独用会出问题
它只能筛掉完全不支持 Grid 的浏览器(比如 IE9),但放行 Safari 10.1、iOS Safari 15.6 这类“半支持”环境——它们认 display: grid,却不支持 gap、fr 单位或 grid-template-areas,结果布局碎裂。
- 只写
@supports (display: grid)→ Safari 10.1 通过检测,但gap: 1rem静默失效 - 加
and (grid-template-columns: 1fr)→ 同时验证 display 和模板语法,能准确筛掉 Safari ≤10.1、IE、Android 4.4 WebView - 别用
@supports (gap: 1rem)→ Firefox 63 以前不支持,反而把大量现代浏览器拦在外面
@supports 块内外的样式怎么安排才安全
IE11 完全忽略整个 @supports 块,连带里面规则都不解析;旧 Android WebView(Chromium 30)甚至不识别 @supports 语法本身,整块被丢弃。所以降级样式绝不能藏在里面。
- ✅ 正确顺序:先写兼容样式(如
display: -ms-grid或float: left+margin),再包现代 Grid 样式进@supports - ❌ 错误写法:
@supports (display: grid) { .grid { display: grid; } }然后外层再写.grid { display: flex; }→ 新浏览器可能残留flex行为,尤其在 iOS Safari 15.4 中子项换行异常 - 降级分支里要显式重置干扰属性:比如
flex-wrap: wrap、align-items: stretch、margin: 0,避免和 Grid 的二维逻辑耦合
移动端和微信 X5 内核的特殊处理
微信 X5 内核 v6.x 之前、Android 4.4 WebView 不支持 display: grid 也不支持 @supports 规则,意味着你写的任何 @supports 块都会被跳过,连降级样式都得靠“浏览器看不懂新语法就自然走默认”这个事实来兜底。
立即学习“前端免费学习笔记(深入)”;
- 所有降级样式(如
display: block+float+box-sizing: border-box)必须写在@supports块之外,且不能依赖任何新属性(比如别用gap,改用margin) - 父容器若用
grid-template-rows: 40px 1fr 60px,子元素启用subgrid时,降级必须手动写死grid-row: 1 / 4,不能指望浏览器推导 - 避免在 subgrid 链路上用
display: contents—— 它会让子元素脱离网格上下文,@supports也救不了
真正麻烦的不是写两套样式,而是 gap、subgrid、fr 单位这些特性在降级时没有等价替代;@supports 只管分流,轨道对齐、间隙控制、跨行逻辑都得人工对齐,稍有偏差就会在 Safari 15.6 这类“灰度兼容”环境下错位。


















