是响应式图像的声明式方案,不执行取数据或计算逻辑,浏览器根据srcset、media、type等属性自主选择加载源。

picture 元素不是“响应式取法”,而是响应式图像的声明式方案
直接说结论: 本身不执行任何“取数据”或“计算适配逻辑”的行为,它只是告诉浏览器:「这里有多个图像源,你按我写的规则自己选一个加载」。所谓“响应式取法”,其实是浏览器根据 srcset、media、type 等属性,结合当前设备 DPR、视口宽度、MIME 类型支持能力,自主决策的结果——开发者不写 JS,也不“取”任何运行时数据。
用 的 media 属性做视口宽度适配
这是最常见也最容易出错的用法。关键在 media 值必须是媒体查询字符串(不是 CSS 类名或 JS 变量),且顺序有影响:
-
media为(max-width: 767px)的必须写在(min-width: 768px)之前,否则小屏设备可能跳过它(浏览器从上到下匹配第一个满足条件的) - 不要写
media="width —— 这是无效语法,会退化为加载的src - 如果所有
都不匹配,浏览器会回退到内部的src,所以不可省略
@@##@@
用 srcset + sizes 配合做 DPR 和视口双适配
当你要同时适配高清屏(2x/3x)和不同宽度容器时, 的 srcset 必须搭配 sizes 才能生效;否则浏览器无法知道“这张图在页面中会占多宽”,也就无法选对分辨率版本:
-
sizes值必须是长度描述符(如100vw、(min-width: 768px) 50vw, 100vw),不能是像素值(400px是合法的,但静态写死会失去响应性) -
srcset中的每个 URL 后必须跟w或x描述符,例如"photo-400w.jpg 400w, photo-800w.jpg 800w",只写逗号分隔的 URL 会被忽略 - Chrome DevTools 的 Network 面板里看实际加载的是哪个资源,比猜更可靠;禁用缓存再刷新,避免误判
@@##@@
type 属性用于格式降级,不是“智能识别”
type 用来声明该 图像的 MIME 类型,浏览器只加载自己支持的类型。它不触发 JS 解析、不调用 API、不“检测”用户环境——只做布尔判断:
立即学习“前端免费学习笔记(深入)”;
- 写
type="image/webp"时,Safari 14+ 才原生支持,旧版 Safari 会跳过该,落到下一个或
- 不要写
type="webp"(缺image/前缀)或type="image/jpg"(应为image/jpeg),这些都会让该失效 - WebP/AVIF 通常比 JPEG 小 30%~50%,但编码耗时高;若服务端未预生成,强行 on-the-fly 转换反而拖慢首屏
@@##@@
真正容易被忽略的点是:所有适配逻辑都发生在 HTML 解析阶段,没有 JS 参与,也没有网络请求前的数据“获取”过程。如果你在控制台看到图像没按预期加载,优先检查 media 语法是否合法、sizes 是否准确描述了布局宽度、以及浏览器是否真的支持你写的 type——而不是去查“为什么没取到数据”。












