<picture>本身不裁剪图片,真正起作用的是<source>组合:media控制视口断点(须互斥且从宽到窄)、srcset提供同断点下DPR选项(仅1x/2x)、type筛选格式支持(AVIF/WebP/JPG需按优先级排序),末尾<img>为必需兜底,含src与alt。

picture 标签本身不决定“多规格”,真正起作用的是 <source> 的组合策略:media 控制视口断点,srcset 提供同一断点下的密度选项,type 筛选格式支持——三者叠加才能覆盖设备宽度、DPR、浏览器能力三个维度。
media 断点必须互斥且覆盖全范围
浏览器按 <source> 顺序匹配,遇到第一个满足 media 的就停。常见错误是断点重叠或留空:
- 错例:
media="(max-width: 768px)"和media="(min-width: 768px)"—— 768px 这个边界值可能被两个都匹配,实际只取第一个,但逻辑不清晰 - 正解:用
(max-width: 768px)/(min-width: 769px) and (max-width: 1200px)/(min-width: 1201px),明确切割 - 必须兜底:所有
<source>都不匹配时,靠末尾的<img>加载,所以<img src="...">不可省略
srcset 在 source 中只管密度,不管尺寸切换
<source> 的 srcset 只接受像素密度描述符(1x, 2x),不能用宽度描述符(400w)——那是 <img> 的 srcset 才支持的用法。
- 正确:
<source media="(max-width: 480px)" srcset="hero-sm.jpg, hero-sm@2x.jpg 2x"> - 错误:
<source media="(max-width: 480px)" srcset="hero-400w.jpg 400w, hero-800w.jpg 800w">(浏览器忽略400w) - 想用
w描述符?必须写在<img>的srcset里,并配sizes属性
type 属性必须放 source 里,且顺序即优先级
浏览器从上到下检查 <source>,遇到第一个 type 受支持的就加载,后续直接跳过。所以 WebP/AVIF 必须写在 JPEG 前面:
立即学习“前端免费学习笔记(深入)”;
- 有效降级:
<source type="image/avif" srcset="hero.avif">→<source type="image/webp" srcset="hero.webp">→<source srcset="hero.jpg"> - 无效写法:
<source srcset="hero.jpg">放最前,即使浏览器支持 AVIF 也会加载 JPG -
type值必须是标准 MIME 类型,image/webp不能写成webp或.webp
img 的 src 和 srcset 是兜底层的完整控制
当所有 <source> 都不匹配,或浏览器根本不认识 <picture> 时,<img> 全权接管。这时它自己的 srcset + sizes 才能生效:
<img src="hero-fallback.jpg" srcset="hero-400w.jpg 400w, hero-800w.jpg 800w" sizes="(max-width: 480px) 100vw, 50vw">- 注意:
<img>的src是必需属性,哪怕写了srcset也得有;alt也必须存在,否则无障碍失败 - 这个兜底层还能用
decoding="async"防止解码阻塞主线程,loading="eager"强制首图立即加载
真正难的不是写对语法,而是理清三层职责:media 切断点、type 筛格式、srcset 分密度——任何一层漏掉或错位,都会导致某类设备加载错图或降级失效。尤其要注意 <source> 里不能混用 w 和 x,这是最容易翻车的地方。



















