source元素按dom顺序从上到下匹配,首个满足media、type等条件的即被选用,后续忽略;兜底source应倒数第二,img为强制最终fallback。

source 元素按 DOM 顺序依次匹配,遇到第一个满足条件的就停止
浏览器不会“综合判断”所有 <source></source>,而是从上到下逐个检查 media、type、srcset + sizes 是否匹配当前环境。一旦某个 <source></source> 满足全部适用条件(比如媒体查询为真、MIME 类型被支持),就立即选用它,后续 <source></source> 被忽略。
常见错误现象:<picture></picture> 显示了低分辨率图,但开发者以为高分辨率 <source></source> 会优先生效——其实是因为高分版写在了下面,而上面某个宽泛的 media="(min-width: 1px)" 已经提前命中。
- 必须把最具体、最高优先级的条件放在最前面(例如
media="(min-width: 1200px) and (prefers-reduced-motion: no-preference)") - 兜底的
<source></source>(如无media或type)建议放在倒数第二位,留给<img>做最终 fallback - 不写
media也不写type的<source></source>等价于media="all",极易误抢匹配权
type 属性只校验 MIME 类型是否被浏览器原生支持,不触发下载
type 的作用纯粹是“准入筛选”:浏览器拿到 <source></source> 后,先查自己能否解码该类型(如 image/webp、image/avif),不支持就跳过这一项,继续看下一个 <source></source>。它不会导致资源预加载或报错,也不影响 srcset 解析逻辑。
使用场景:为现代格式提供降级路径。例如 WebP 支持率高但 Safari 旧版不支持 AVIF,就可以这样组织:
<picture><source srcset="photo.avif" type="image/avif"><source srcset="photo.webp" type="image/webp"> @@##@@ </source></source></picture>
- 即使
photo.avif地址 404,只要浏览器声明支持image/avif,它仍会尝试请求——type不校验文件是否存在 - 部分安卓 WebView 对
image/avif返回support但实际解码失败,需结合真实设备测试 - 不要依赖
type实现“格式智能选择”,它只是硬性开关;真正的适配还得靠srcset+sizes配合 DPR 和视口宽度
media 查询在解析时已计算完毕,不响应后续 resize 或 prefers-color-scheme 切换
<source></source> 的 media 属性只在元素插入 DOM 或首次计算样式时求值一次。之后窗口缩放、系统主题切换、甚至 JS 动态修改 matchMedia 结果,都不会触发 <picture></picture> 重新选源。
这意味着:如果你用 media="(prefers-color-scheme: dark)" 加载暗色图标,用户中途切到亮色模式,图片不会自动切换——除非整个 <picture></picture> 被移除再重建,或手动调用 picture.querySelectorAll('source').forEach(s => s.remove()); 并重插。
- 响应式图标/背景图等需要动态切换的场景,
<picture></picture>不是银弹;更适合用 CSSbackground-image+@media或 JS 监听matchMedia -
media中不能使用相对单位(如em),仅接受绝对单位(px)、关键字(all,screen)和标准媒体特性(width,height,orientation等) - 调试时可用
window.matchMedia("(min-width: 768px)").matches手动验证当前是否命中某条规则
img 标签不是备选方案,而是强制 fallback 终点
当所有 <source></source> 都因 media 不匹配或 type 不支持而被跳过时,浏览器一定会加载 <img src="photo.jpg" alt="..."> 的 src(或 srcset),无论其格式多老旧、尺寸多不准。这个行为不可绕过,也没有“跳过 <img> 再试下一个 <source></source>”的机制。
容易踩的坑是误把 <img> 当成“可选降级”,结果在不支持任何 type 的极老浏览器中加载了未压缩的 4K 图片,或在 src 指向 404 时页面显示空白占位符。
-
<img>必须存在,且必须有src(哪怕只是 1×1 的 placeholder);否则整个<picture></picture>渲染为空白 - 不要给
<img>设srcset后就以为它能响应式——它的srcset仅在无有效<source></source>时启用,且不参与<source></source>的 DPR 计算流程 - 若想让
<img>也享受响应式能力,最稳妥做法是让它成为最后一个<source></source>(不带media和type),然后把原<img>的src移到该<source></source>的srcset中
media、type、srcset 三者嵌套组合时,一个顺序颠倒或遗漏的 media 就会让整套响应式策略失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











