响应式图片的核心是让浏览器选择最合适的图;仅适用于艺术指导或格式降级,日常宽度适配用即可,误用会破坏预加载。

响应式图片的核心不是“自动适配”,而是“让浏览器选最合适的图”
直接结论:<picture></picture> 不是万能的,它只在需要**艺术指导(art direction)** 或**格式降级(如 WebP → JPEG)** 时才值得用;日常宽度适配,<img srcset> 就够了。很多人一上来就套 <picture></picture>,结果白写了冗余标签,还破坏了浏览器预加载机制。
什么时候必须用 <source></source> 配合 <picture></picture>
只有两种真实场景绕不开:构图裁剪变化(比如移动端显示人脸特写、桌面端显示全身)或格式兼容兜底(比如优先用 WebP,老浏览器 fallback 到 JPEG)。其他情况——比如只是同一张图缩放到不同宽度——请用 <img srcset> + sizes。
-
<source></source>的media属性必须是媒体查询(如(max-width: 768px)),不能写像素值或百分比 - 多个
<source></source>按顺序匹配,第一个满足条件的生效,后面的被忽略 -
<source></source>必须放在<picture></picture>内部,且必须在<img>标签之前 - 每个
<source></source>必须有srcset,但可以没有type;如果有type,值必须是 MIME 类型(如image/webp),浏览器不识别的类型会跳过该<source></source>
<img> 在 <picture></picture> 里不是备选,而是必填的 fallback
<picture></picture> 本身不渲染内容,它只是个容器;真正显示的是内部的 <img>。这个 <img> 必须存在,且至少带 src 和 alt —— 它不是“最后兜底图”,而是“当所有 <source></source> 都不匹配或不支持时的默认图”。
- 如果忘了写
<img>,页面会出现空白,控制台无报错,极难排查 -
<img>的srcset和sizes依然有效,会被浏览器用于宽度适配(只要没被上面的<source></source>截断) -
<img>的src应该指向一个广泛兼容的格式(如 JPEG 或 PNG),不要放 WebP - 别给
<img>加width/height属性来“控制尺寸”,那会覆盖 CSS 响应式行为;用 CSS 控制
常见错误:WebP 降级写法失效的三个原因
想用 WebP 提升加载速度,但实际加载的还是 JPEG?大概率卡在这三点:
- 服务器没正确返回
Content-Type: image/webp,导致浏览器认为文件损坏而跳过该<source></source> -
<source type="image/webp"></source>放在了<source type="image/jpeg"></source>后面——浏览器按顺序匹配,即使支持 WebP 也会先选到 JPEG - 用了
srcset但没配sizes,浏览器无法判断视口宽度下的目标尺寸,退回到加载src,绕过了所有srcset逻辑
示例(正确顺序):
<picture><source type="image/webp" srcset="hero-400.webp 400w, hero-800.webp 800w" sizes="(max-width: 768px) 400px, 800px"><source type="image/jpeg" srcset="hero-400.jpg 400w, hero-800.jpg 800w" sizes="(max-width: 768px) 400px, 800px"><img src="hero-fallback.jpg" alt="Hero banner"></source></source></picture>
注意:所有 srcset 中的宽度描述符(400w)单位是“像素源图宽度”,不是 CSS 像素,也不是设备像素比——这点最容易混淆。










