modernizr 默认不启用 flexbox 和 grid 检测,需在官网勾选或配置构建工具注入;类名作用于 ,css 选择器应写为 html.flexbox .container;modernizr.load() 已废弃,改用原生 import() 或动态脚本加载;modernizr 与 @supports 各司其职,前者用于 js 降级兜底,后者用于 css 渐进增强,且 modernizr 必须同步或早于 css 加载以避免 fouc。

Modernizr 检测不到 flexbox 或 grid 怎么办
Modernizr 默认不启用所有检测项,flexbox 和 grid 这类较新的 CSS 特性需要显式开启。如果你只用了官网默认构建(或 npm 安装的预编译版),大概率它们压根没被包含进去。
- 去 Modernizr 官网下载页,勾选
flexbox、cssgrid(注意不是cssgridlegacy)等你需要的检测项再生成 - 用 npm 的话,别直接
import Modernizr from 'modernizr'——它只是空壳;得配合modernizr-loader(Webpack)或手动配置构建流程,把检测项注入 - 检查生成后的
Modernizr对象:在控制台输Modernizr.flexbox,返回true/false才算生效;如果报undefined,说明检测项没打包进去
用 Modernizr 类名写 CSS 时样式不生效
Modernizr 会在 标签上添加类名(比如 flexbox 或 no-flexbox),但很多人忘了 CSS 选择器必须匹配这个层级。
- 错误写法:
.flexbox .container { display: flex; }—— 这要求.flexbox是.container的祖先,但它实际在上 - 正确写法:
html.flexbox .container { display: flex; }或更稳妥的.flexbox .container(前提是确保没有其他同名类干扰) - 注意浏览器兼容性陷阱:IE8 不支持多类选择器,如果还要兼容它,得用
.flexbox.container这种无空格写法,且确保 Modernizr 已加载完成才执行样式表(避免 FOUC)
Modernizr.load() 已废弃,现在怎么按需加载 CSS/JS
Modernizr.load() 在 Modernizr 3.0 就被移除了,它原本是 yepnope.js 的封装,现在官方只负责特性检测,加载逻辑得自己来。
- 检测后手动加载:
if (!Modernizr.webp) { const img = document.createElement('img'); img.src = 'fallback.jpg'; }—— 简单场景直接操作 DOM - 需要动态引入资源时,用原生
import()(ES 模块)或document.createElement('script'),配合onload回调处理依赖顺序 - 别把 Modernizr 当加载器用:它不管理资源缓存、并发、超时,复杂场景推荐用
loadjs或require.js这类专用工具,Modernizr 只管“问浏览器有没有这个能力”
为什么加了 Modernizr,CSS 里用 @supports 还要留着
Modernizr 和 @supports 解决的是不同层面的问题:前者是 JS 运行时检测,后者是 CSS 原生条件规则。它们不互斥,也不替代。
立即学习“前端免费学习笔记(深入)”;
-
@supports能让浏览器原生跳过不支持的声明,减少解析开销;而 Modernizr 类名触发的 CSS 是强制应用的,哪怕浏览器其实已支持,也照常走那套逻辑 - 典型误用:用 Modernizr 加载一个 polyfill,又在 CSS 里用
@supports (display: grid)写同一套布局——结果可能 polyfill 没生效,但@supports也没覆盖到老浏览器 - 建议组合策略:用 Modernizr 做降级兜底(如加载
flexibility.js),用@supports做渐进增强(如给新浏览器加gap属性),二者分工明确
真正容易被忽略的是:Modernizr 的检测结果依赖脚本执行时机。如果它在 DOMContentLoaded 之后才加载, 上的类名就会晚于 CSS 解析,导致首屏样式错乱。务必把它放在 里同步加载,或者用 defer 但确保早于样式表。










