浏览器只加载第一个匹配的,按顺序逐条检查,遇首个media为真或type受支持且srcset可用即停止;media必须完整合法,type不匹配则整条静默跳过,是强制兜底节点,缺则留白。

浏览器只认第一个匹配的 <source></source>,不“综合判断”
浏览器对 <picture></picture> 的处理是线性短路匹配:从上到下逐条检查 <source></source>,遇到第一个 media 为真、或 type 受支持且 srcset 有可用资源,就立刻加载它,后面所有 <source></source> 和 <img> 的 srcset 全部跳过。
这不是“最优解”,而是“第一个合法解”。所以顺序不是风格问题,是逻辑前提。
- 把最具体、限制最强的规则放最前(例如
media="(min-width: 1440px) and (min-resolution: 2dppx)") - 通用兜底(如
max-width: 480px)必须放最后 - 断点值不能重叠,比如
max-width: 768px和min-width: 768px在恰好 768px 宽时都为真,但浏览器只取前者,后者永远不执行
media 写错一个括号,整条 <source></source> 就静默失效
media 值必须是完整、合法的媒体查询字符串。写成 media="max-width: 768px"(缺括号)或 media="768px"(无媒体类型、无单位、无比较符),浏览器直接忽略该 <source></source>,不报错、不警告、不 fallback 到下一条。
常见无效写法:
-
media="screen and max-width: 768px"→ 缺少括号,应为screen and (max-width: 768px) -
media="(max-width: 768)"→ 单位缺失,必须是768px -
media="(min-width: 768px) (orientation: landscape)"→ 缺and连接,语法错误
type 不匹配时,浏览器不会“尝试下一个”,而是跳过整条 <source></source>
type="image/avif" 或 type="image/webp" 的作用,是让浏览器在支持该 MIME 类型时才考虑这条 <source></source>。一旦不支持,这条规则就彻底出局——它不会降级去查自己的 srcset,也不会触发后续 <source></source> 的匹配。
典型失效场景:
- Safari 15 之前不支持
image/avif,若你把 AVIF 放最前且没配 WebP 或 JPEG 后备,页面直接空白 - 服务器返回
image/webp文件但响应头是Content-Type: image/jpeg→ Chrome 标记为blocked:mime-type,该<source></source>被跳过 -
<source type="image/webp" srcset="hero.webp"></source>+<source media="(max-width: 480px)" srcset="hero-mobile.jpg"></source>→ 如果 WebP 不被支持,第二条不会自动生效,除非它自己也满足media条件且当前视口命中
<img> 不是可选装饰,漏掉或写错就留白
<img> 是强制 fallback 节点,不是“锦上添花”。它必须存在、必须在所有 <source></source> 之后、必须带 src 和 alt 属性。否则:
- 所有
<source></source>都未命中时,页面图片区域为空白(尤其 Safari / iOS 旧版) -
<img src="">或<img>自闭合 → 空白,不是 404 -
<img src="fallback.jpg">但没写alt→ 无障碍失败,部分 UA 渲染异常 - 想用 DPR 适配?
srcset中的2x、3x只在<img>上生效,<source></source>里的2x完全被无视
真正容易被忽略的,是你得为每套断点准备多套分辨率图(@1x/@2x/@3x),而这些图本身必须按构图提前裁好——<picture></picture> 不做任何裁剪,它只负责把对的文件名交给浏览器。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











