modernizr 不加载 css 补丁,仅同步注入类名(如 no-flexbox),应通过预置 css 类选择器控制样式,而非动态插入 link 标签;需手动勾选检测项,确保 modernizr.js 置于 head 顶部。

Modernizr 本身不加载任何 CSS 补丁,它只负责检测并写入 html 类名;按需加载 CSS 必须由你手动触发,且不能依赖已废弃的 Modernizr.load()。
为什么直接用 Modernizr 检测后加 link 标签会失效
常见错误是:在 DOMContentLoaded 里判断 Modernizr.flexbox === false,然后动态插入 <link rel="stylesheet" href="flex-fallback.css"> —— 这看似合理,但存在两个硬伤:
- 页面已开始渲染,插入的 CSS 可能导致 FOUC(闪动)或样式覆盖不及时
- IE9 及以下不支持
rel="stylesheet"动态加载,onload回调不可靠 - 现代浏览器中,CSS 加载是异步的,无法保证在 DOM 渲染前就位
正确做法:用类名控制预置 CSS,而非运行时加载
Modernizr 的核心价值在于“同步注入类名”,所有样式适配应提前写死,靠类名开关。这是最稳定、兼容性最好、也最符合其设计意图的方式。
- 确保
modernizr.js放在最顶部,早于所有<link>样式表 - CSS 中直接使用
html.no-flexbox .container或更简洁的.no-flexbox .container(前提是没冲突) - 否定类名永远是
no-开头,比如.no-border-radius,不是.no-css-border-radius - 避免写
.modernizr-no-flexbox—— Modernizr 默认不加前缀,写了就匹配不上
真要动态加载 CSS 补丁?用原生 import() 或 fetch + insertRule
仅当补丁体积大、且只影响特定交互模块(如某个图表组件)时才考虑动态加载。此时 Modernizr 仅作判断依据,不参与加载逻辑。
- 推荐写法:
if (!Modernizr.cssgrid) { import('./grid-polyfill.css'); }(ES 模块环境) - 兼容旧环境:
if (!Modernizr.webp) { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = 'webp-fallback.css'; document.head.appendChild(link); } - 注意:不要用
document.styleSheets[0].insertRule()手动注入规则 —— 容易因样式表未就绪而失败,且难调试 - 加载后别忘了清空或重置相关元素的 class,否则新旧样式可能打架
真正容易被忽略的是:Modernizr 检测项默认不包含 flexbox、cssgrid 等新特性,官网下载页必须手动勾选;如果控制台里 Modernizr.flexbox 是 undefined,那所有基于它的 CSS 和 JS 分支都无效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











