<picture>是唯一原生支持按设备特性自动选图的语义化方案,必须用于不同构图、格式降级、暗色模式切换或高DPR精细适配场景;其<source>按顺序匹配media,末尾<img>为强制兜底。

<picture> 是唯一能原生实现“按设备特性自动选图”的语义化方案,不需要 JS,也不依赖 CSS 媒体查询模拟。它不是锦上添花的装饰,而是解决带宽浪费、DPR 不匹配、格式兼容性问题的基础设施。
什么时候必须用 <picture> 而不是 <img>
当你的图片需要同时满足以下任意一条时,<img> 的 srcset + sizes 就不够用了,必须上 <picture>:
- 不同屏幕宽度下要加载**完全不同构图**的图(比如桌面端横幅大图,移动端裁剪为竖版人物特写)
- 想优先提供
webp或avif,但需 fallback 到jpg(浏览器不支持新格式时自动降级) - 需要根据
prefers-color-scheme切换亮色/暗色主题下的图片(如 logo 有深色版和浅色版) - 同一页面中某张图需适配高 DPR 设备(2x/3x),但又不能靠简单缩放解决(比如图标含精细文字)
<source> 的 media 属性到底怎么写才可靠
media 是 <source> 的核心判断依据,但它只接受媒体查询表达式,不支持 JS 逻辑或自定义条件。常见误区是直接照搬 CSS 媒体查询写法却忽略执行时机:
- 浏览器在解析 HTML 阶段就评估
media,**不等 CSS 加载完成**,所以不能依赖 class 或自定义属性 -
min-width: 768px指的是视口宽度(viewport width),不是元素宽度,别和container queries混淆 - 多个
<source>按顺序从上到下匹配,**第一个满足条件的即生效**,后续被忽略 —— 所以宽屏条件要放在前面 - 推荐写法:
media="(min-width: 1200px) and (resolution >= 2dppx)",但注意 Safari 对复合查询支持较晚(iOS 16.4+)
<img> 在 <picture> 里不是可选项,而是强制兜底
<picture> 必须以 <img> 结尾,且该 <img> 的 src 和 alt 属性不可省略 —— 即使你写了所有可能的 <source>,浏览器仍会把 <img> 当作最终 fallback:
立即学习“前端免费学习笔记(深入)”;
- 如果所有
<source>的media都不匹配(比如用户禁用了媒体查询),就加载<img src="..."> -
<img>可以带srcset和sizes,它自己也能做分辨率适配,和外层<picture>不冲突 - 别给
<img>写width/height属性来“撑开容器”:它只负责显示,尺寸应由 CSS 控制;否则可能破坏响应式行为 - 错误示例:
<picture><source srcset="a.webp" type="image/webp"></picture>—— 缺少<img>,结果是空白
真正容易被忽略的点在于:浏览器对 <source> 的格式探测是同步进行的,但对 type 属性的支持程度不一。Chrome 和 Firefox 识别 avif 很快,Safari 直到 iOS 17 才稳定支持。所以如果你写了 type="image/avif" 却没配好 fallback,老设备就会跳过整个 <source>,直奔 <img>。这不是 bug,是设计使然 —— 它要求你始终把兼容性当作前提,而不是事后补救。



















