CSS.supports() 可轻量检测 Flexbox 新特性支持度,但需注意 IE/旧 WebView 不兼容、必须用完整声明、Safari 对双参数形式支持差;@supports 适合 CSS 渐进增强;DOM 渲染检测可兜底语法检测失效场景。

用 CSS.supports() 检测 Flexbox 新特性是否可用
现代浏览器基本都支持 display: flex,但像 gap、flex-wrap: wrap-reverse、justify-content: space-evenly 这类较新的 Flexbox 特性,支持度仍有断层。直接调用 CSS.supports('gap: 1rem') 是最轻量、无依赖的检测方式。
注意几个关键点:
-
CSS.supports()在 IE 中完全不可用(Edge 12+ 才开始支持),老 Android WebView(4.3 及更早)也不稳定,需兜底 - 检测
gap必须写完整声明:CSS.supports('gap: 1rem'),不能只写'gap'或加括号'(gap: 1rem)' - 检测
flex-wrap: wrap-reverse要带值:CSS.supports('flex-wrap: wrap-reverse'),只写'flex-wrap'会返回false - 某些 Safari 版本(16.4–17.3)对双参数形式
CSS.supports('gap', '1rem')返回false,务必统一用单参数字符串形式
用 @supports 规则做 CSS 层面的渐进增强
@supports 是纯 CSS 的特性开关,适合在样式表中直接分发不同布局逻辑,避免 JS 注入 class 带来的 FOUC 风险。
常见组合写法:
立即学习“前端免费学习笔记(深入)”;
- 检测
gap并降级为margin:@supports (gap: 1rem) { .flex-list { display: flex; gap: 1rem; } } @supports not (gap: 1rem) { .flex-list > * + * { margin-left: 1rem; } } - 同时检测
flex-wrap和justify-content: space-evenly:@supports (flex-wrap: wrap-reverse) and (justify-content: space-evenly) { .nav { display: flex; flex-wrap: wrap-reverse; justify-content: space-evenly; } } - 不推荐嵌套多个
@supports not,容易漏写回退规则;建议“现代样式优先 + 单层not回退”结构
手动创建 DOM 元素检测 flex-gap 的真实渲染行为
CSS.supports('gap: 1rem') 只表示语法被识别,不代表 gap 在 flex 容器中能正确生效——Safari 14.1–15.6 就存在 row-gap 不起作用的 bug。这时需要运行时渲染检测。
核心思路是构造一个两行 flex 容器,设 rowGap 为 1px,看实际高度是否为 1px(排除内容撑高干扰):
- 必须用
flex-direction: column+row-gap,因为column-gap在某些旧 Safari 中被忽略 - 子元素必须是空 div,避免字体、内边距等干扰
scrollHeight - 插入到
document.body后立即读取,否则可能因样式未计算而误判 - 检测完必须移除临时元素,否则影响后续布局或性能监控
示例函数:
function supportsFlexGap() {
const flex = document.createElement('div');
flex.style.display = 'flex';
flex.style.flexDirection = 'column';
flex.style.rowGap = '1px';
flex.appendChild(document.createElement('div'));
flex.appendChild(document.createElement('div'));
document.body.appendChild(flex);
const isSupported = flex.scrollHeight === 1;
document.body.removeChild(flex);
return isSupported;
}别把 Modernizr 当万能胶,尤其对 Flexbox
Modernizr 的 flexbox 检测只反映 display: flex 是否存在,对 gap、flex-wrap 等子特性完全不覆盖;它的 flexboxlegacy 和 flexboxtweener 已被弃用多年,现在几乎没意义。
更现实的问题是:
- Modernizr 加载时机晚于 CSS 解析,
往往首屏已渲染完毕,导致回退样式失效 - 你写了
.no-flexbox-gap .list,但忘了配.flexbox-gap .list,结果新旧浏览器都走 fallback - 检测脚本放在
<body>底部,而关键 CSS 在<head>,中间存在样式闪动窗口 - 只用一两个 Flexbox 特性时,Modernizr 的 12KB(min+gzip)远不如手写 10 行
CSS.supports()或@supports
真正容易被忽略的不是“怎么检测”,而是“检测之后要不要信”。比如 CSS.supports('gap: 1rem') 返回 true,但 Safari 15.4 下 gap 在 flex-direction: column 中仍不生效——这种场景必须靠 DOM 渲染检测兜底,不能只看语法支持。


















