@include retina() 仅静态生成多倍屏媒体查询,不感知设备dpr也不加载图片;需确保@2x文件真实存在、路径匹配、background-size显式设置,否则导致模糊或404。

SCSS的@include retina()到底干了什么
@include retina() 只是编译时静态生成几组 @media 规则,比如 @media (-webkit-min-device-pixel-ratio: 2) 和 @media (min-resolution: 2dppx)。它不感知设备当前的 dpr,也不加载图片——浏览器自己决定用哪条规则、发哪个请求。
常见错误现象:开发者工具里看到高分媒体查询被命中,但 Network 面板显示 icon@2x.png 返回 404;或者图加载成功,却拉伸变形、边缘发虚。
- 文件必须真实存在,且命名严格匹配:
@include retina("logo.png")默认拼出logo@2x.png,不是logo_2x.png或logo@2x.jpg - 路径必须和最终部署结构一致:Webpack/Vite 中
public/目录、CDN 域名、CSS 输出路径三者要对齐 -
background-size必须显式写,不能靠默认值——auto会导致平铺或拉伸
为什么 background-size 不写清楚就一定模糊
Retina 屏下,1 个 CSS 像素对应多个物理像素。如果 icon@2x.png 是 100×100px,而容器逻辑尺寸是 50×50px,就必须写 background-size: 50px 50px,否则浏览器按原始尺寸渲染,结果是放大两倍后插值模糊。
- 传
cover或contain仅控制缩放方式,不自动加background-position: center,居中裁剪需手动补 - 若用固定尺寸(如
24px 24px),确保和容器 CSS 尺寸一致,否则比例错乱 - 别信 mixin 默认值:
$size: auto是最常踩的坑,永远显式传参
参数顺序混乱导致编译结果不可控
不同项目引入的 _retina.scss 实现差异极大,参数顺序可能为 ($path, $ratio, $size, $position) 或 ($path, $size, $ratio),$size 默认值可能是 auto、100% 100% 或空字符串。
- 传
$ratio: 2通常只生成 @2x 查询;要同时支持 @2x 和 @3x,得确认该 mixin 是否内置多级判断(多数不支持) - 混用
retina-bg()和retina()很危险:前者常漏掉no-repeat或background-origin,会覆盖基础样式 - 若项目已用 WebP/AVIF,
@include retina()不会自动替换后缀,得自己加str-replace()逻辑,或干脆换方案
比 @include retina() 更稳的替代方案
直接用 CSS 原生 image-set():浏览器运行时按当前 dpr 动态选源,不依赖文件命名、不预生成冗余媒体查询、调试成本更低。
示例:background-image: image-set("icon.png" 1x, "icon@2x.png" 2x, "icon@3x.png" 3x);
- 兼容性:Safari 9+、Chrome 39+ 支持;IE 和 Edge ≤18 不支持,需 fallback 到传统 media query
- 它不解决路径 404 问题,但彻底规避了 “mixin 参数写错 → 媒体查询白生成” 的反复验证
- 如果项目已用 Retina.js,优先走 JS 方案:给元素加
data-rjs="2",它会自动替换内联背景图 URL,且能处理非标准命名
真正容易被忽略的点是:所有方案都绕不开文件存在性与路径可达性验证——再完美的 mixin 或 image-set(),只要 icon@2x.png 在服务器上 404,就永远模糊。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











