picture 标签本身不“适配”,真正起效的是 source 的 media/srcset/type 及 img 的 srcset/sizes;写错顺序、漏 img、混用描述符会导致静默回退至 fallback 图。

直接结论:picture 标签本身不“适配”,它只是把选择权交给浏览器;真正起效的是 <source> 的 media、srcset、type,以及最外层 <img> 的 srcset 和 sizes。写错顺序、漏掉 <img>、混用描述符,都会导致只加载 fallback 图。
为什么写了 <picture> 却始终加载同一张图
这不是浏览器“不支持”,而是结构或语法触发了静默回退:
-
media值写错:比如media="max-width: 768px"(缺括号)或media="768px"(非媒体查询语句),浏览器直接忽略该<source> -
<source>有srcset但没配media或type:该<source>不参与匹配,等于白写 -
<img>缺src:页面图片区域留空,不是报错,是静默失败 - Network 面板看到
blocked:mime-type:服务器返回的Content-Type和你写的type="image/webp"不一致(比如返回text/plain)
<source> 的 media 必须从宽到窄或从窄到宽,但顺序决定匹配结果
浏览器从上到下扫描 <source>,遇到第一个满足条件的就停,后面的全忽略——这不是“多选”,是“短路匹配”。
- ✅ 推荐顺序(窄屏兜底):
media="(max-width: 480px)"→media="(min-width: 481px) and (max-width: 1024px)"→media="(min-width: 1025px)" - ❌ 错误写法:把
max-width: 480px放最前,小屏设备永远卡在这条,宽屏规则根本没机会生效 - ⚠️ 断点别重叠:比如
max-width: 768px和min-width: 768px在恰好 768px 宽时都为真,但浏览器只认第一个,行为不可控 - 单位不能省:
768是无效媒体查询,必须写成768px
srcset 的 1x/2x 只在 <img> 上生效,<source> 里写 2x 被无视
适配视网膜屏(DPR=2/3)只认 1x、2x、3x 这种写法;w 描述符不管用,除非你同时配了 sizes 并想按布局宽度算——但那是另一套逻辑。
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确结构:
<source media="(max-width: 480px)" srcset="icon-sm-1x.png, icon-sm-2x.png">+<img src="icon-lg-1x.png" srcset="icon-lg-1x.png 1x, icon-lg-2x.png 2x"> - ❌ 常见错误:
<source srcset="a@2x.png 2x"><img src="a@1x.png">→ 小屏设备只加载a@2x.png,但 DPR=1 时本该用1x - ⚠️ 混用
w和x:photo-400w.jpg 400w, photo@2x.jpg 2x是未定义行为,Chrome 可能整个srcset忽略 -
<img>的src不是可选项,而是强制兜底;没它,整个<picture>在不匹配时渲染为空白
验证是否真加载了 @2x 图,别信 window.devicePixelRatio
window.devicePixelRatio 返回 2 只说明设备支持高 DPI,不代表图片就加载了 @2x 版本。真正决定加载哪张图的是 HTML 结构和浏览器解析逻辑。
- 唯一可靠验证方式:打开 Chrome DevTools → Network 面板 → 刷新页面 → 筛选 Img 类型 → 找到对应图片 → 右键「Copy image src」→ 粘贴确认 URL 含
@2x或@3x - 模拟不同 DPR:DevTools → ⚙️ → Sensors → Device pixel ratio → 改为 1 / 2 / 3,然后 硬刷新(Ctrl+Shift+R),普通刷新可能走缓存
- 注意检查
<img>是否被 CSS 强制设了固定宽高(如width: 300px; height: 200px),会导致@2x图被压缩模糊



















