保真靠 srcset 与 sizes 正确搭配且避免浏览器误入宽度匹配模式;写了 @2x 仍模糊主因是 sizes 属性导致 dpr 匹配失效,dpr 适配必须由 的 srcset 承担, 仅负责格式降级、尺寸断点或艺术指导。

picture 本身不保真,保真靠的是你把 srcset 和 sizes 搭配对了,且没让浏览器误入宽度匹配模式。
为什么写了 @2x 还是模糊
最常见原因:你在 <img> 上加了 sizes 属性(哪怕只是 sizes="100vw"),导致浏览器彻底忽略 1x/2x 描述符,转而按视口宽度选图——此时 DPR=2 的设备也可能加载 @1x.png。
- ✅ 正确写法:
<img src="btn@1x.png" srcset="btn@1x.png 1x, btn@2x.png 2x, btn@3x.png 3x"> - ❌ 错误写法:
<img src="btn@1x.png" srcset="btn@1x.png 1x, btn@2x.png 2x" sizes="32px">→2x永远不触发 -
<source></source>里的2x根本不被解析,浏览器只取它srcset中第一个 URL
picture 里 source 到底该干什么
<source></source> 不负责 DPI 切换,只负责三件事:格式降级(type="image/webp")、大范围尺寸断点(media="(min-width: 768px)")、或艺术指导(比如横屏换构图)。DPR 适配必须全交给最外层 <img> 的 srcset。
- 正确结构示例:
<picture><source type="image/webp" srcset="btn@1x.webp 1x, btn@2x.webp 2x"><source media="(min-width: 768px)" srcset="btn-large@1x.png 1x, btn-large@2x.png 2x"><img src="btn@1x.png" srcset="btn@1x.png 1x, btn@2x.png 2x"></source></source></picture> - 错误结构:
<source media="(max-width: 480px)" srcset="btn-small@2x.png 2x"></source>→ 小屏永远加载@2x,哪怕 DPR=1 -
<source></source>必须在<img>前面,否则整个picture失效
怎么确认真的加载了 @2x
window.devicePixelRatio === 2 只说明设备支持高 DPI,不代表图片就用了 @2x。唯一可信方式是看网络请求。
- 打开 Chrome DevTools → Network 面板 → 刷新页面
- 筛选类型为
Img→ 找到对应按钮图标 - 右键 →
Copy image src→ 粘贴 URL 确认含@2x或@3x - 模拟不同 DPR:DevTools → ⚙️ → Sensors → Device pixel ratio → 改为 1 / 2 / 3,然后 **硬刷新(Ctrl+Shift+R)**
CSS 导致的“假模糊”比资源错更隐蔽
即使 @2x 图成功加载,仍可能糊——大概率是 CSS 强制缩放或未设响应式尺寸。
- 如果
<img>有固定width: 32px; height: 32px,那 64×64 的@2x图会被压缩进 32×32 容器,像素信息直接丢弃 - 必须加
max-width: 100%; height: auto,否则图片超出父容器后失比例或被裁剪 - 用伪元素叠加滤镜时,别给容器本身加
filter: blur(),否则文字、按钮全糊;要用::before+z-index: -1隔离模糊层
真正容易被忽略的点:DPR 匹配逻辑只存在于 <img> 的 srcset,且要求无 sizes;<source></source> 的 media 和 2x 是互斥的;验证必须查 Network,不能信控制台打印值或肉眼判断。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











