IE11及旧版Edge不解析<picture>标签,必须在其中末尾放置兼容性<img>作为降级回退,且<img>的src须为JPEG/PNG,不可含srcset或sizes,多<source>按格式新旧倒序排列,构建时生成双版本HTML最可靠。

picture 标签在 IE 和旧版 Edge 中根本不会解析
直接用 <picture> 无法让 IE11 或 Edge 16 以下版本显示任何图片——它们会忽略整个标签,连里面的 <img> 也不执行。这不是样式问题,是解析层面的缺失。
真正能落地的方案不是“增强 picture”,而是“降级 fallback”:确保每个 <picture> 内部都带一个语义正确、位置合规的 <img>,且该 <img> 的 src 指向一张通用兼容图(如 WebP 的 PNG 备份),同时不设 srcset 或 sizes。
-
<img>必须是<picture>的**最后一个子元素**,否则旧浏览器可能跳过它 - 不要给
<img>加srcset——IE 会报错并中断后续资源加载 - 避免用
src指向 WebP:IE 不支持,会显示空白或破损图标
如何让现代浏览器用 WebP,老旧系统自动回退到 JPEG/PNG
关键不在 <picture> 本身,而在 <source> 的 type 属性是否被识别。Chrome/Firefox/Safari 会检查 type="image/webp" 并加载对应 srcset;IE/旧 Edge 完全忽略 <source>,直接渲染末尾的 <img>。
所以结构必须严格遵循这个顺序:
立即学习“前端免费学习笔记(深入)”;
<picture> <source type="image/webp" srcset="/hero.webp 1x, /hero@2x.webp 2x"> <source type="image/avif" srcset="/hero.avif 1x, /hero@2x.avif 2x"> <img src="/hero.jpg" alt="Hero image"> </picture>
- 多个
<source>按格式新旧倒序写(WebP 在前,AVIF 在后):新浏览器取第一个支持的,旧浏览器全跳过 -
<img>的src必须是 JPEG 或 PNG,且尺寸适配默认视口(不能依赖sizes计算) - 不要给
<img>加width/height属性来“控制响应式”——它只负责兜底,响应行为由 CSS 管理
为什么 lazyload + picture 组合在旧系统上容易挂掉
很多 lazyload 库(如 lazysizes)靠监听 IntersectionObserver 触发加载,但 IE11 完全不支持该 API,且部分库在检测失败后不会降级到 scroll 或 load 监听,导致 <img> 的 src 始终为空。
- 若必须懒加载,对旧系统单独加一层判断:
if ('IntersectionObserver' in window)再初始化 lazyload - 或者改用简单方案:给
<img>的src直接写死,不参与懒加载——毕竟它只是兜底图,体积应足够小 - 避免在
<source>上写data-srcset然后靠 JS 搬运:IE 解析不到<source>,JS 也读不到它的 dataset
构建时自动生成兼容图比运行时判断更可靠
别指望前端 JS 检测 userAgent 或 document.createElement('picture').canPlayType 来动态插入 HTML——逻辑复杂、易出错,且首次渲染仍可能闪白屏。
真正稳的方式是在构建阶段就产出两套资源:
- 一份含
<picture>的 HTML(供现代浏览器) - 一份把
<picture>替换为纯<img src="xxx.jpg">的 HTML(供旧系统定向分发) - 用 Webpack/Vite 插件或 CI 脚本批量处理
.html文件中的<picture>块,比客户端 JS 判断干净得多
最常被忽略的一点:旧系统兜底图的压缩质量要重新评估——JPEG 未必比 WebP 大多少,但若用 Photoshop 默认导出,体积可能翻倍。用 cwebp -q 80 对比 mozjpeg -quality 80 实测,差距往往不到 15%。



















