picture 标签是 img 的容器而非替代品,必须包含至少一个带 src 或 srcset 的 img 作为兜底,配合 source 实现响应式图片;media 优先匹配断点,type 切换格式,srcset+sizes 适配分辨率。

picture 标签不是 img 的替代品,而是它的容器
<picture></picture> 本身不渲染图片,它只是为 <img> 提供一组候选源。最终显示什么,取决于浏览器根据 <source></source> 规则匹配到的首个有效选项,再交给内部的 <img> 去加载和渲染。漏掉 <img> 或没写 src(或 srcset)会导致空白——这是最常见的“图片不显示”原因。
典型结构必须包含:
- 零个或多个
<source></source>(带media、srcset、type等属性) - 一个必需的
<img>,且至少要有src或srcset,以及alt
用 media 属性做断点切换,优先级高于 srcset
当你要按视口宽度加载不同尺寸的图片(比如移动端用小图、桌面用大图),<source media="(max-width: 768px)" srcset="small.jpg"></source> 是最直接的方式。浏览器从上到下扫描 <source></source>,遇到第一个匹配 media 查询的就停止,并使用它的 srcset;其余 <source></source> 被忽略。
注意点:
-
media值必须是合法的媒体查询,比如"(min-width: 1024px)",不能写成"1024px" - 没有
media的<source></source>相当于media="all",应放在最后,否则会截断后续规则 -
<img>的src是兜底项,仅在所有<source></source>都不匹配时生效
用 type 属性切换格式(如 webp / avif),需服务端支持 MIME
想让支持 image/avif 的浏览器加载更小的 avif 图,不支持的退回到 jpg,就用 type:
<picture><source srcset="photo.avif" type="image/avif"><source srcset="photo.webp" type="image/webp"> @@##@@ </source></source></picture>
关键约束:
- 浏览器只检查
type值是否被原生支持,**不验证文件实际格式**——如果photo.avif实际是 jpg,就会加载失败(控制台报 404 或解码错误) - 服务器必须对
.avif文件返回Content-Type: image/avif,否则 Chrome 等浏览器会拒绝解析 -
type和media可共存,但media仍先匹配;建议分开用:纯格式切换用type,纯尺寸切换用media
srcset + sizes 组合用于分辨率适配,别漏掉 sizes
当目标是高 DPR 设备(如 iPhone Retina、Windows 高分屏)加载 2x 图,应该用 <source srcset="small-1x.jpg 1x, small-2x.jpg 2x"></source>,但更推荐统一用 srcset + sizes(尤其配合 media):
<source media="(max-width: 480px)" srcset="sm-400w.jpg 400w, sm-800w.jpg 800w" sizes="100vw"></source>
这里 sizes 告诉浏览器:“在该 media 条件下,这张图将占满视口宽度”,浏览器据此从 srcset 中选最接近的资源。漏掉 sizes 会导致浏览器无法正确计算,可能始终加载最小图。
常见疏忽:
-
sizes值必须是响应式长度(如"50vw"、"(max-width: 600px) 100vw, 50vw"),不能是像素值"400px" -
srcset中的w描述的是图片固有宽度(像素),不是容器宽——它和sizes共同参与计算,不是一一对应 - 不要在
<img src="photo.jpg" alt="描述">上重复写sizes;它只对紧邻的<source></source>生效
最易被忽略的是:所有 <source></source> 必须位于 <img> 之前,且 <img> 必须存在并具备可加载的 src 或 srcset。哪怕你只想要格式切换,也得留一个 <img>——否则老浏览器或禁用 JS 的环境里,图片区域就是空的。

前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











