retina屏模糊主因是css未声明高清图及未匹配容器尺寸与物理像素,需用媒体查询+background-size同步控制;less中应封装支持2x/3x的retina-bg mixin并确保资源存在。

为什么 background-image 在 Retina 屏上模糊
直接写 background-image: url(icon.png) 时,浏览器在 2x 屏上仍会拉伸 1x 图片,导致像素点被插值模糊。本质是 CSS 没告诉浏览器“这张图有更高清版本”,也没控制容器尺寸与图像物理像素的对应关系。
关键不是“换图”,而是让容器尺寸(CSS 像素)和图像资源的物理像素匹配。比如一个 16px 宽的图标,在 2x 屏上应使用 32px 物理宽的图,并把容器设为 width: 16px; height: 16px;,再用 background-size: 16px 16px; 缩放到视觉大小。
- 只替换
url()不够,必须同步调整background-size和容器尺寸 - 不能依赖 JS 动态判断 dpr,CSS 层面需静态可推导
- Less 中无法运行时读取设备 dpr,所以得靠媒体查询 + 预定义倍率
用 .retina-bg() Mixin 自动生成 2x 规则
手动写 @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) 太重复。封装成 Mixin 后,只需传入普通图路径,自动补全 2x 版本和 background-size:
.retina-bg(@url, @w: auto, @h: auto) {
background-image: url(@url);
background-size: @w @h;
@at2x-url: ~"@{url}"; // 先存原路径
@at2x-url: replace(@at2x-url, ".png", "@2x.png");
@at2x-url: replace(@at2x-url, ".jpg", "@2x.jpg");
@at2x-url: replace(@at2x-url, ".jpeg", "@2x.jpeg");
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
background-image: url(@at2x-url);
background-size: @w @h;
}
}
调用:.retina-bg("icon.png", 16px, 16px); → 输出标准图 + 媒体查询内 2x 图,且 background-size 保持一致。
- 注意
replace()是 Less 内置函数,只支持单次替换,所以按后缀顺序处理 -
@w/@h设为auto时,background-size: auto可能导致 2x 图被错误缩放,建议显式传入尺寸 - 如果项目用 WebP 或 SVG,需额外扩展
replace分支
适配 3x 屏或自定义倍率怎么办
单纯加 @media (-webkit-min-device-pixel-ratio: 3) 不够——3x 图若按 2x Mixin 逻辑生成,会被命名为 icon@2x@2x.png,明显错误。得区分倍率层级:
.retina-bg(@url, @w, @h, @ratio: 2) when (@ratio = 2) {
// ……同上,但用 @ratio 控制后缀
@atx-url: replace(@url, ".png", "@{ratio}x.png");
// 其余类似
}
.retina-bg(@url, @w, @h, @ratio: 2) when (@ratio = 3) {
@atx-url: replace(@url, ".png", "@{ratio}x.png");
@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 384dpi) {
background-image: url(@atx-url);
background-size: @w @h;
}
}
调用:.retina-bg("icon.png", 16px, 16px, 3);
- Less 不支持运行时动态拼接媒体查询条件,所以必须为每个
@ratio单独写@media块 - 实际项目中 3x 资源极少,多数只需 2x;盲目加 3x 支持反而增大构建体积
- 若用 Webpack,更推荐用
responsive-loader在构建时切图,而非 CSS 层面 hack
SVG 替代方案比 @2x PNG 更简单
对图标类资源,直接用 background-image: url(icon.svg) 几乎无需处理:SVG 是矢量,缩放无损,且现代浏览器对 background-size 的解析足够稳定。
- 仅当 SVG 含 CSS 样式或 JS 交互时才需注意兼容性(如 IE11 不支持 SVG 中的
<style></style>) - 如果设计稿明确要求“必须用 PNG”,那 SVG 方案就不适用——别为了省事绕过需求
- 混合使用时,不要让
.retina-bg()接收 SVG 路径,否则生成的@2x.svg无意义
高清屏适配真正的难点不在写多少行 Less,而在于图片资源是否真实存在对应倍率版本、构建流程是否校验了这些文件的存在性。没图,再好的 Mixin 也只输出 404。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











