必须用<picture>,否则旧浏览器(如IE、Safari≤13.1)会空白无报错;<source type="image/webp">需同时满足type前缀正确、服务器Content-Type精确匹配及URL可访问,否则静默跳过,最终依赖<img>兜底。

必须用 <picture>,不能只靠 <img srcset> 或单个 <img> 标签——否则旧浏览器(IE、Safari ≤13.1、旧 Android WebView)直接空白,且无任何报错提示。
为什么 <picture> 里 <source type="image/webp"> 不生效
浏览器不是“不支持 WebP”,而是根本没走到加载那步:它先校验 type 值是否在白名单中,再检查服务器返回的 Content-Type 是否完全匹配。两者任一出错,整条 <source> 就被静默跳过。
-
type="webp"❌ 错误:缺image/前缀;正确写法是type="image/webp" -
type="image/jpg"❌ 错误:JPEG 的标准 MIME 是image/jpeg,不是jpg - Nginx 未配置
types { image/webp webp; }→ .webp 文件被当成application/octet-stream返回 → 浏览器拒绝加载 - CDN 没透传
Accept: image/webp请求头 → 后端无法协商格式,统一返回 JPEG →<source>加载失败,退到<img>
<source> 的顺序和 <img> 的 src 怎么配才不退错
顺序不是“建议”,是执行逻辑:浏览器从上到下逐条检查,第一个 type 支持 + 资源可解码就停。兜底的 <img> 不是备选,是所有老环境唯一入口。
- AVIF 必须放最前:
<source srcset="a.avif" type="image/avif">(Chrome 120+/Firefox 120+ 可用) - WebP 居中:
<source srcset="a.webp" type="image/webp">(覆盖 iOS 14+、Android 4.0+、主流桌面) - JPEG/PNG 不能写成第三个
<source>,必须塞进<img src="a.jpg">的src属性里 -
<img>的src必须是静态可直访路径,如logo.jpg,禁用logo.jpg?format=webp或 CDN 动态转码地址 -
<img>必须带alt,否则语义缺失,无障碍与 SEO 全挂
图片尺寸不一致导致降级后拉伸或跳变
视觉跳变的根源不是格式切换,而是不同格式图片的 intrinsic 尺寸(原始像素宽高)不一致。浏览器按 WebP 的元数据算一次高度,换到 JPEG 又按另一套重排,layout shift 自然发生。
立即学习“前端免费学习笔记(深入)”;
- 用
file logo.webp和file logo.jpg确认二者像素尺寸是否完全相同(如都是 800×450) - CMS 导出或 tinypng 压缩可能抹除 JPEG 的 EXIF 宽高字段,导致浏览器误判为“无尺寸”
- 生成 JPEG 时加强制尺寸参数:
convert -resize 800x450\! input.png output.jpg - 补 EXIF 字段:
exiftool -ImageWidth=800 -ImageHeight=450 logo.jpg - 无法保证所有格式尺寸一致时,改用容器锁比例:
style="aspect-ratio: 16 / 9; object-fit: cover;",Safari ≤15.2 需 fallback 到padding-top技巧
最容易被忽略的点:所有格式图片的 URL 必须真实可访问,且服务端返回的 Content-Type 必须和 type 属性一字不差——差一个斜杠,整个降级链就断了。



















