retina屏背景图模糊的根本原因是图片物理尺寸未匹配设备像素比(dpr),如容器400×300px在dpr=2时需800×600px图,仅靠background-size无法修复;必须提供对应倍率高清图并配合image-set()或@media查询兜底。

background-image在Retina屏模糊的根本原因
不是CSS写错了,而是你给的图没匹配设备像素比(dpr)。比如容器 CSS 宽高是 400px × 300px,在 dpr=2 的 iPhone 上,浏览器实际需要渲染 800×600 物理像素——但你只提供了 400×300 的图,它只能硬拉伸,结果就是糊。用 background-size: cover 或 100% 100% 都救不回来,因为源头是图不够大。
image-set() 写法必须带 fallback 且顺序不能错
image-set() 不是“写了就清晰”,它只在 Safari 9+、Chrome 39+、Edge 16+ 里生效,Firefox 和 IE 完全不解析。一旦出错,页面就直接退回到 1x 图,还看不出报错。
- 必须写 fallback:
background-image: url("bg.png"); background-image: image-set("bg.png" 1x, "bg@2x.png" 2x);——后一条覆盖前一条,顺序反了就失效 -
bg@2x.png文件物理尺寸必须是bg.png的 2 倍(如 800×600 → 1600×1200),不能靠 PS 放大“假装”高清 - 必须显式设
background-size: 400px 300px(按设计稿逻辑尺寸),否则 2x 图会以原像素渲染,变成 800×600 的 CSS 尺寸,撑爆容器 - 构建工具(如 Vite)默认不处理
image-set()里的路径,"bg@2x.png"得真出现在dist/目录下,否则 404 后不会降级到 1x,而是空白
@media 查询是真正兜底的刚需方案
仅靠 image-set() 在安卓 WebView、旧版 Safari 或 Firefox 里大概率失效。媒体查询才是兼容性最稳的 fallback,而且必须手动写两套规则。
- 基础规则放前面:
.hero { background-image: url("bg.png"); background-size: 400px 300px; } - 高清覆盖写后面:
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) { .hero { background-image: url("bg@2x.png"); } } - 用
min-resolution: 2dppx比192dpi更可靠,避免单位换算偏差 - 伪元素(
::before)里用时,别忘了加content: ""、display: block和显式width/height,否则背景根本没渲染区域
别碰 background-size: 100% 100% 和 image-rendering
background-size: 100% 100% 是模糊加速器——它强制非等比拉伸,尤其在 dpr≠1 时失真更明显。image-rendering 对 background-image 完全无效,CSS 背景图根本不响应这个属性。
- 优先用
cover或contain,并确保高清图物理尺寸 ≥ 容器 CSS 尺寸 × 最大可能 dpr(比如按 3x 准备) - 如果必须适配多档 dpr(2x/3x),media query 要拆成两层:
(min-resolution: 2dppx)和(min-resolution: 3dppx),不能混在一起 -
picture和srcset对背景图无效——它们只作用于<img>标签,background-image不解析srcset或<source></source>
bg@2x.png 是否真被加载。打开 Chrome DevTools 的 Network 面板,过滤图片,切到 iPhone 模拟器,刷新看请求的是哪张图——很多“模糊”问题,其实只是 @2x 路径 404 或压根没触发媒体查询。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











