浏览器按<source>的media属性从上到下匹配首个满足条件的源,匹配即停止;未匹配则加载<img>。关键在于media值合法、顺序正确、覆盖无隙,且<img>必须有src,w描述符需配sizes,sizes仅在<img>上生效。

浏览器只按 <source> 的 media 属性从上到下匹配第一个满足条件的源,匹配后立刻停止;没匹配到就加载 <img> —— 这就是“智能匹配”的全部逻辑,没有自动推断、没有兜底重试。
为什么写了 media 却只加载一张图?
不是浏览器不“智能”,而是条件没写对或顺序错了:
-
media="(max-width: 768px)"和media="(min-width: 768px)"相邻时,如果前者在后,后者永远不生效(因为 768px 宽度先被max-width: 768px匹配) -
media="768px"或media="tablet"是非法值,浏览器直接忽略该<source> - 所有
<source>的media都不满足,但<img>没写src,结果页面留白——<img>的src是强制要求,不是可选 - 用
w描述符(如photo-400w.jpg 400w)却漏了sizes,浏览器无法估算显示宽度,只能退回到<img src>
<source> 的 media 必须覆盖常见视口断点
断点不是越多越好,关键是连续无空隙。典型三段式写法(从小到大):
<picture> <source media="(max-width: 480px)" srcset="hero-sm.jpg"> <source media="(min-width: 481px) and (max-width: 1023px)" srcset="hero-md.jpg"> <source media="(min-width: 1024px)" srcset="hero-lg.jpg"> <img src="hero-fallback.jpg" alt="首页横幅"> </picture>
注意:481px 和 1024px 是硬边界,避免相邻区间重叠或遗漏;min-width: 481px 比 min-width: 480px 更安全,防止某些 UA 对边界像素处理不一致。
立即学习“前端免费学习笔记(深入)”;
如何同时适配视口宽度 + 设备像素比(DPR)?
靠组合:先用 <source> 的 media 锁定视口范围,再在每个 srcset 里用 x 描述符响应 DPR:
<picture> <source media="(max-width: 480px)" srcset="hero-sm-1x.jpg 1x, hero-sm-2x.jpg 2x"> <source media="(min-width: 481px)" srcset="hero-lg-1x.jpg 1x, hero-lg-2x.jpg 2x"> <img src="hero-lg-1x.jpg" srcset="hero-lg-1x.jpg 1x, hero-lg-2x.jpg 2x" alt="横幅图"> </picture>
关键点:
- 浏览器先看
media:如果是 400px 宽的手机,就进第一个<source>;如果是 1200px 宽的桌面屏,就进第二个 - 再看当前设备 DPR:DPR=2 时,从已选
<source>的srcset中挑2x版本;DPR=1 就选1x -
<img>的srcset不是摆设——当所有<source>都不匹配时,它得自己扛起 DPR 适配责任
sizes 必须写在 <img> 上,且不能省
如果你用了 w 描述符(比如 photo-800w.jpg 800w),sizes 就不是可选项,而是决策前提:
-
sizes告诉浏览器:“这张图在页面中大概占多宽”,例如sizes="(max-width: 768px) 100vw, 50vw" - 浏览器用这个宽度 × 当前 DPR,算出需要多少像素宽的图,再去
srcset里找最接近的w值 -
<source>上写的sizes会被完全忽略,只认<img>的 - 漏掉
sizes→ 浏览器无法估算 → 全部回退到<img src>单图加载
真正容易被忽略的,是 sizes 和 CSS 布局的耦合:它必须真实反映图片在页面中的渲染宽度。如果用 CSS 把图片强制缩成 300px 宽,但 sizes 写的是 100vw,浏览器就会选错图。



















