Modernizr通过在html标签添加类名(如flexbox、webp、cssgrid)暴露浏览器能力,CSS需用这些类名写选择器实现样式分支,否定类为no-前缀,自定义检测用Modernizr.addTest注入。

Modernizr检测到的类名怎么用在CSS里
Modernizr不是用来“运行”的,它只负责在<html>标签上加一堆描述能力的类名,比如flexbox、webp、csstransforms。你得靠这些类名写CSS选择器来控制样式分支。
常见错误是以为Modernizr会自动加载polyfill或切换class——它不会。它只做一件事:把浏览器支持情况翻译成HTML类名。
- 确保Modernizr脚本在
<head>里加载(越早越好),否则页面可能闪动 - 检查生成的
<html class="js flexbox webp csstransforms no-touch">是否出现,没出现说明脚本没执行或配置错 - 别写
.modernizr-flexbox这种,Modernizr默认不加前缀,就是.flexbox - 否定类名是
no-<feature>,比如.no-webp表示不支持WebP,可用于回退到.jpg背景图
如何给不支持CSS Grid的老浏览器写降级布局
Grid是典型“有就用,没有就fallback”的场景。Modernizr能告诉你cssgrid是否存在,但要注意:IE10/11支持的是旧版语法(display: -ms-grid),Modernizr的cssgrid类只标新版(display: grid)支持情况,IE11默认是no-cssgrid。
所以不能只靠.cssgrid开新布局,得配合.no-cssgrid写降级:
立即学习“前端免费学习笔记(深入)”;
/* 新式布局 */
.cssgrid .container { display: grid; grid-template-columns: 1fr 2fr; }
<p>/<em> 降级为Flex </em>/
.no-cssgrid .container { display: flex; }</p><p>/<em> 再降级为float(针对连Flex都不支持的IE9) </em>/
.no-cssgrid.no-flexbox .container { overflow: hidden; }
.no-cssgrid.no-flexbox .container > div { float: left; width: 50%; }- Modernizr默认不检测
cssgridlegacy,如需区分IE10/11,得手动添加自定义检测或用cssgrid+ UA判断 - 别在
.no-cssgrid里写display: grid,那会被忽略,但可能干扰调试 - Flex降级要小心
flex-wrap兼容性,IE10不支持,得用no-flexwrap再细分
为什么webp检测失败但浏览器明明支持
Modernizr的webp检测是通过创建<canvas>画一张WebP图片再读取data URL来判断的,不是查UA或静态特性表。失败原因很实际:
- 页面没开启HTTPS(某些浏览器在HTTP下禁用WebP编码)
- Canvas被同源策略阻塞(比如图片跨域但没加
crossOrigin) - 用了精简版Modernizr构建,漏掉了
webp检测模块 - 浏览器支持WebP解码但不支持编码(如部分安卓WebView),而Modernizr测的是编码能力
验证方式:打开控制台,执行Modernizr.webp,看返回true还是false;再手动跑一段canvas检测代码对比结果。
自定义检测怎么加进Modernizr并影响CSS类名
官方构建工具不直接暴露API加检测,但你可以用Modernizr.addTest在加载后注入:
Modernizr.addTest('intersectionobserver', 'IntersectionObserver' in window);
// 这会让<html>多出一个 intersectionobserver 或 no-intersectionobserver 类关键点:
- 必须在Modernizr脚本执行完之后调用,否则
Modernizr对象还没定义 - 检测函数返回
true时加intersectionobserver,返回false时加no-intersectionobserver - 不要重复检测已存在的特性(比如
Modernizr.addTest('flexbox', ...)会覆盖原逻辑,导致意外行为) - 自定义类名会参与CSS层叠,注意优先级——
.no-intersectionobserver .list比.list权重高
复杂点在于,很多新API(比如CSS.supports)本身就有兼容性梯度,单靠一个布尔值很难覆盖所有边缘case。这时候类名只是起点,还得结合@supports或JS逻辑兜底。










