直接写@media (-webkit-min-device-pixel-ratio: 2) 不够用,因它仅覆盖旧版 webkit 浏览器,漏掉 firefox、chrome 等支持 min-resolution 的现代浏览器,且无法适配 dpr=3 或非整数比设备,必须叠加 (min-resolution: 2dppx) 和 (min-resolution: 192dpi) 才能全端兼容。

为什么直接写 @media (-webkit-min-device-pixel-ratio: 2) 不够用
因为不同设备的像素比不统一,iOS、Android、MacBook 的 device-pixel-ratio 可能是 2、3,甚至 Windows 上某些缩放设置会触发非整数比(如 1.25、1.5)。硬编码 @media 查询不仅维护成本高,还容易漏掉 min-resolution 这类更现代的标准写法。SCSS 混合宏必须同时覆盖 -webkit-min-device-pixel-ratio、min-resolution(单位为 dppx 和 dpi),否则在 Firefox 或新版 Chrome 中可能失效。
@mixin retina-bg 必须接收哪些参数
只传一张图?那没法 fallback。真正可用的混合宏至少要支持三张图:普通图、2x 图、3x 图(可选)。路径需区分处理,避免重复拼接后缀;同时允许覆盖背景属性(如 no-repeat、center center),否则每次调用还得额外写 background-size。
-
$image-path:基础路径,例如"icon-home"(不含扩展名) -
$ext:默认"png",便于统一改格式 -
$size:用于background-size,推荐设为auto或具体尺寸(如24px 24px) -
$background-props:字符串,例如"no-repeat center center",直接注入background声明
怎么生成兼容所有浏览器的多层 @media 规则
不能只写一个 @media。必须分三层输出:针对 WebKit 的 -webkit-min-device-pixel-ratio、针对标准的 min-resolution: 2dppx、以及兜底的 min-resolution: 192dpi(因 1dppx = 96dpi,2dppx = 192dpi)。否则在 Safari 旧版或 IE Edge 中背景图会不切换。
@mixin retina-bg($image-path, $ext: "png", $size: auto, $background-props: "") {
background: url("#{$image-path}.#{$ext}") #{$background-props};
background-size: $size;
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx), (min-resolution: 192dpi) {
background-image: url("#{$image-path}@2x.#{$ext}");
}
@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 3dppx), (min-resolution: 288dpi) {
background-image: url("#{$image-path}@3x.#{$ext}");
}
}
实际使用时最常踩的坑
图没换上?大概率是路径拼错了。SCSS 编译时不会校验文件是否存在,@2x.png 少个 @ 或扩展名大小写不一致(比如 PNG vs png),就静默回退到普通图——你根本看不出问题。
- 确保
@2x和@3x图真实存在,且命名与宏中拼接逻辑严格一致 - 如果用 Webpack 或 Vite,注意它们的 asset 处理插件(如
url-loader)可能自动重命名,导致@2x路径失效 -
background-size设为auto时,若原图和 @2x 图宽高比不同,会出现拉伸——此时应显式设为contain或具体像素值 - 不要在同一个选择器里多次调用该宏,CSS 层叠会导致
background-image被覆盖,只生效最后一个
高分屏适配不是加个 @2x 就完事,关键在媒体查询的完备性和资源路径的确定性。一旦路径或查询条件漏一条,用户就在某台设备上看到模糊图,而你本地根本复现不了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











