<picture> + <source type> + <img src> 是唯一原生、零JS、SEO友好、不发额外请求的降级方案;它通过浏览器从上到下匹配首个支持的type并严格依赖服务器正确返回对应MIME类型,<img src>作为强制兜底必须为可直接访问的JPEG/PNG。

直接用 <picture> + <source type> + <img src> 三件套,是唯一原生、零 JS、SEO 友好、不发额外请求的降级方案。其他方式要么靠 JS 补救(断网即失效),要么只改后缀不改 MIME(旧浏览器静默留白)。
为什么 <img src="x.webp"> 会白屏
不是浏览器“兼容性差”,而是它根本不认识 image/webp 这个 MIME 类型。Safari ≤13.1、IE、旧版 Android WebView 遇到就跳过,不加载、不报错、不 fallback——页面直接留空。你写的只是 URL,但服务器返回的 Content-Type 不在浏览器白名单里,资源就被静默丢弃了。
常见错误包括:
-
type="webp"(缺image/前缀)→ Safari 直接忽略 -
type="image/jpg"(应为image/jpeg)→ Chrome 可能侥幸加载,Safari 必挂 -
<img src="logo.jpg?format=webp">→ 旧浏览器发请求,服务器返回 406 或损坏数据 - 漏掉
<img>标签 → 整个<picture>结构被忽略,IE 和旧 WebView 全空白
<source> 的顺序和 type 必须严格匹配浏览器能力
浏览器从上到下逐条检查 <source>,遇到第一个 type 被支持 *且* 资源可解码(路径对、格式合法、网络通)就停,不再往下看。这不是“备选”,是“优先级队列”。
立即学习“前端免费学习笔记(深入)”;
推荐顺序(2026 年实测覆盖最广):
<picture> <source srcset="logo.avif" type="image/avif"> <source srcset="logo.webp" type="image/webp"> <img src="logo.jpg" alt="Logo"> </picture>
说明:
-
image/avif放最前:Chrome 120+ / Firefox 120+ / Edge 120+ 稳定支持;旧 Safari 自动跳过 -
image/webp次之:覆盖 iOS 14+、Android 4.0+、所有桌面现代浏览器 -
<img src>必须是静态 JPEG/PNG 地址,不能带查询参数,必须能在地址栏直接打开 - 不要写第三个
<source type="image/jpeg">—— 它不起降级作用,<img>才是强制兜底
<img> 的 src 是最后防线,但容易被忽视
很多人以为写了三个 <source> 就万事大吉,结果 IE 或旧 WebView 里一片空白——因为没写 <img>,或写了但 src 是无效路径。
关键约束:
-
<img>必须存在,且含src和alt,否则语义缺失、无障碍失败、SEO 折损 -
src值必须指向一个真实可访问的 JPEG 或 PNG,比如/assets/logo.jpg,不是/assets/logo.jpg?x-oss-process=... - 所有格式图片(AVIF/WebP/JPEG)的宽高、裁剪比例、构图必须一致,否则切换时视觉跳变
- CDN 若未透传
Accept请求头(如Accept: image/avif,image/webp),后端无法按需返回对应格式,<source>会因 406 失败而跳过
别指望 CSS background-image 做格式降级
background-image: url(x.webp) 在不支持 WebP 的浏览器里同样白屏,而且它不支持 type、srcset 或任何降级声明。纯 CSS 方案没有 fallback 能力。
如果必须用背景图:
- 只用于装饰性图片(如 banner 底纹、图标背景),非关键内容
- 用
@supports (background-image: url(x.webp))包裹 WebP 版本,再写一层 JPEG 回退 - 但注意:IE 完全不支持
@supports,仍需靠其他手段兜底
真正需要格式降级的图片(如商品主图、头像、LOGO),只能走 <picture> 路线。复杂点在于所有格式文件得提前生成、路径对齐、MIME 配置正确——少一个环节,降级就静默失效。



















