图片降级本质是 fallback,需用 <picture> 实现格式协商或 onerror 处理网络失败;CSS background-image 不支持降级,纯 HTML 无法一劳永逸。

图片降级的本质是 fallback,不是“备用图”那么简单
HTML 本身没有“降级”机制,所谓图片降级,是指当 <img> 的 src 不可用(404、跨域拒绝、格式不支持)时,浏览器不会自动尝试其他地址——它只会显示破损图标或空白。真正能触发 fallback 的,只有 <picture> + <source> 的响应式/格式协商流程,或 JavaScript 主动监听错误后替换 src。
<picture> 是唯一原生支持格式/尺寸降级的方案
它不解决网络失败问题,但能按 MIME 类型或媒体条件提供替代源,比如优先加载 WebP,不支持时回退到 JPEG:
<picture> <source srcset="photo.webp" type="image/webp"> <source srcset="photo.avif" type="image/avif"> <img src="photo.jpg" alt="描述"> </picture>
注意三点:
-
<source>按顺序匹配,第一个满足条件的生效,后续被忽略 -
type属性必须精确匹配浏览器支持的 MIME 类型(image/webp不能写成webp) -
<img>是必需的 fallback 元素,没有它整个<picture>不会渲染
网络失败时只能靠 JavaScript 监听 onerror
这是应对 404、CORS 或临时断网的唯一可靠方式。直接在 <img> 上绑定 onerror 最简单,但要注意避免死循环:
立即学习“前端免费学习笔记(深入)”;
<img src="broken.jpg"
onerror="this.onerror=null; this.src='fallback.jpg';"
alt="描述">
关键细节:
- 必须设
this.onerror=null,否则换源失败时会再次触发onerror,导致无限递归 - 不要用内联函数调用外部方法(如
onerror="handleError(this)"),除非你确保该函数已定义且无副作用 - 如果 fallback 图也加载失败,建议设为 data URL 占位符(如
data:image/svg+xml,%3Csvg...%3E),避免二次报错
CSS background-image 无法降级,别白费劲
很多人试图用 CSS 的 background-image 多值写法实现降级,比如:
div { background-image: url("a.webp"), url("b.jpg"); }
这是无效的。CSS 不支持 fallback 链,只取第一个有效声明;后续声明会被完全忽略。真要兼容,只能用 JS 动态检测 document.createElement('img').src = 'test.webp' 是否能加载成功,再切换 class。
复杂点在于:WebP/AVIF 支持检测不能只看 UA,得实际加载测试;而图片错误监听又得防重复触发。这两件事没法用纯 HTML 一劳永逸,得按场景选策略——格式协商用 <picture>,网络异常用 onerror,别混着来。



















