image-set() 根据设备像素比(dpr)选图而非屏幕分辨率;firefox v128及之前完全不解析,整条声明被静默丢弃;常见失效原因包括浏览器兼容性、语法错误(如引号缺失、1x缺失)、-webkit-顺序错误及构建别名未解析。

image-set() 不是根据“屏幕分辨率”引入背景图,而是根据设备像素比(DPR)选图——iPhone 15 Pro(DPR=3)和 MacBook Pro(DPR=2)哪怕物理分辨率差一倍,只要 DPR 相同,就会加载同一张 @2x.png。Firefox(v128 及之前)完全不解析它,整条声明被静默丢弃,背景图直接消失。
为什么写了 image-set() 却没效果
最常见原因不是写错了,而是浏览器压根没执行它:
- Firefox v128 及更早:整条
background-image: image-set(...)被跳过,DevTools 里该行被划掉,Console 无报错 - Safari ≤15.3:如果漏了
1x项,整条声明被忽略(不是只跳过 2x) - 路径没加引号,比如写成
url(logo@2x.png)而非url("logo@2x.png"),部分 Safari 会校验失败 - 用了 Webpack/Vite 的
@/assets别名——image-set()不走构建工具解析,运行时 404
-webkit-image-set() 必须写在 image-set() 前面
顺序错误会导致 Safari ≥16.4 忽略 1x 图,最终只加载 2x 甚至空白:
background-image: url("logo@1x.png");
background-image: -webkit-image-set(url("logo@1x.png") 1x, url("logo@2x.png") 2x);
background-image: image-set(url("logo@1x.png") 1x, url("logo@2x.png") 2x);
关键点:
-
-webkit-版本必须在标准版之前 -
1x不能省略,也不能写成1或1dppx - 所有
url()必须统一用双引号或单引号包裹 - 三行中的路径、空格、单位必须完全一致,否则某些浏览器会整条丢弃
什么时候该放弃 image-set() 改用媒体查询
当你需要同时响应屏幕宽度和 DPR 时,image-set() 就失效了:
- iPad Air(DPR=2,宽 820px)和 Windows 笔记本(DPR=1,宽 1920px)需要完全不同尺寸的图,但
image-set()给的永远是同一组@1x/@2x - 想让手机竖屏加载
hero-mob@2x.jpg、桌面加载hero-desk@2x.jpg?image-set()不支持按宽度选图 - 所有图片仍可能被预加载,无法控制加载时机——它不是异步机制,也不感知网络条件
真正可控的做法是用 @media 分层覆盖,例如:
@media (max-width: 767px) {
.hero {
background-image: url("hero-mob@1x.jpg");
background-image: -webkit-image-set(url("hero-mob@1x.jpg") 1x, url("hero-mob@2x.jpg") 2x);
background-image: image-set(url("hero-mob@1x.jpg") 1x, url("hero-mob@2x.jpg") 2x);
}
}
@media (min-width: 768px) {
.hero {
background-image: url("hero-desk@1x.jpg");
background-image: -webkit-image-set(url("hero-desk@1x.jpg") 1x, url("hero-desk@2x.jpg") 2x);
background-image: image-set(url("hero-desk@1x.jpg") 1x, url("hero-desk@2x.jpg") 2x);
}
}
注意:每个断点内仍需保留三行叠加写法,不能只靠媒体查询“救” image-set() 的兼容性缺陷。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











