结论是:用实现多规格产品图,核心不是“让图片变大变小”,而是按设备视口宽度选构图、按dpr选清晰度、按浏览器能力选格式——三者叠加,缺一不可。

直接说结论:用 <picture></picture> 实现多规格产品图,核心不是“让图片变大变小”,而是按设备视口宽度选构图、按 DPR 选清晰度、按浏览器能力选格式——三者叠加,缺一不可。
为什么不能只靠 img + CSS 做产品图适配
电商页面里,手机端要突出商品主体(比如裁切掉背景只留草莓特写),桌面端要展示包装+场景(整盒九宫格+环境光),这不是缩放能解决的。单纯用 <img src="strawberry.jpg"> 配 CSS width:100%,会导致:小屏加载大图浪费流量、大屏拉伸模糊、Retina 屏文字边缘发虚。浏览器根本不知道你“想给用户看什么”,只会机械下载并渲染单张图。
用 media + srcset 实现“断点裁切 + 密度适配”
这是最常用也最容易出错的一层。关键在于:<source></source> 的 media 控制“在哪种屏幕宽度下启用哪套构图”,其 srcset 再负责“这套构图里,1x/2x 屏该加载哪个文件”。
- 每个
<source></source>的media必须覆盖连续区间,比如(max-width: 480px)、(min-width: 481px) and (max-width: 768px)、(min-width: 769px);漏掉 481–768 之间的规则,平板就会 fallback 到<img> -
srcset里混用w和x描述符(比如"a-400w.jpg 1x, b-800w.jpg 2x")会导致整个srcset被浏览器静默忽略,最终只加载<img src> -
<img>的src必须存在且可访问,否则不匹配任何<source></source>时页面留白——别指望它只是“备用”,它是强制兜底项
示例(手机裁切特写 + 桌面全景):
<picture><source media="(max-width: 480px)" srcset="strawberry-mobile@1x.jpg 1x, strawberry-mobile@2x.jpg 2x"><source media="(min-width: 481px)" srcset="strawberry-desktop@1x.jpg 1x, strawberry-desktop@2x.jpg 2x"> @@##@@ </source></source></picture>
加 type 属性实现 WebP/AVIF 格式降级
同一张图,WebP 通常比 JPG 小 30%~50%,AVIF 还能再压 20%。但老浏览器不认 type="image/webp",所以必须把现代格式 <source></source> 放在前面,JPG <source></source> 或 <img src="strawberry-desktop@1x.jpg" alt="新鲜草莓"> 放后面。
-
type只校验 MIME 类型,不校验文件扩展名;srcset="photo.avif" type="image/avif"写对了,Chrome 会加载,Safari 15.4 以下会跳过 - 不要在同一个
<source></source>里既写type又写media还塞sizes——逻辑太重易错;优先保证type+srcset正确,再叠加其他维度 -
<img>不支持type,所以它的src必须是通用格式(JPG/PNG),否则 Safari 旧版直接不显示
示例(WebP 优先,JPG 保底):
<picture><source srcset="strawberry.webp" type="image/webp"><source srcset="strawberry.jpg"> @@##@@ </source></source></picture>
容易被忽略的硬性细节
调试时 Network 面板看到加载了错误尺寸的图,大概率不是浏览器 bug,而是这几个地方写错了:
-
<source></source>的media值不是合法 CSS 媒体查询(比如写成media="mobile"或media="768px"),浏览器直接跳过该<source></source> -
<img>缺alt—— 不影响加载,但违反无障碍规范,部分 SEO 工具会报错 - 所有
srcset和src路径必须真实存在;404 不报 JS 错误,只会静默 fallback 到下一个候选,得清缓存后看 Network 真实请求路径 -
sizes属性只对<img src="strawberry.jpg" alt="新鲜草莓">有效,写在<source></source>上完全被忽略;如果用了w描述符却没写sizes,浏览器无法估算所需像素宽度,可能加载过小或过大图
真正起作用的是浏览器在 HTML 解析阶段的原生匹配逻辑,不是 JS 控制。写错一个引号、少一个括号、media 条件有间隙,整个 <picture></picture> 就退化成单图加载——这点比 CSS 媒体查询更严格。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











