必须三重声明@media查询(-webkit-min-device-pixel-ratio:2、min-resolution:192dpi、min-resolution:2dppx),否则safari 14+、旧ie及windows高dpi设备会漏适配;retina-bg mixin需自动处理路径、尺寸、svg跳过、@2x文件产出;1px边框须按dpr分层缩放;断点用em而非px以规避dpr干扰;sass仅固化规则,真实适配依赖css媒体查询、html视口与构建工具协同。

直接结论:别只靠 @media (min-resolution: 2dppx),必须组合 (-webkit-min-device-pixel-ratio: 2) 和 (min-resolution: 192dpi) 三重声明,否则在 Safari 14+、旧版 IE 或 Windows 高 DPI 设备上会漏适配。
为什么单写 min-resolution: 2dppx 不够用
2dppx 是标准单位,但 IE 完全不识别,Safari 13 及更早版本支持不稳定,Windows Surface 等设备可能报告 192dpi 却不满足 2dppx 条件。只依赖它等于放弃兼容性兜底。
-
min-resolution: 192dpi覆盖 Windows 高 DPI 和部分旧 Android -
-webkit-min-device-pixel-ratio: 2是 Safari/Chrome 旧版本事实标准 -
min-resolution: 2dppx是现代浏览器首选,但必须和前两者并列,不能替代
@mixin retina-bg() 必须同时处理路径、尺寸与格式边界
高清图替换不只是换 url(),background-size 错位会导致拉伸,SVG 混入时又得跳过媒体查询——这些都得在 mixin 内部收敛。
- 传入的
$image-path必须是无后缀路径(如"icons/arrow.png"),mixin 自动拼@2x - 原图的
background-size必须原样复用,不能写死100% 100%—— PNG 常用contain,SVG 多用100% 100%,混用会错乱 - 若传入 SVG 路径,需加
$is-svg: true参数,mixin 内直接跳过媒体查询块 - Webpack/Vite 构建时必须真实产出
@2x文件,且路径未被 hash 重命名,否则运行时 404
1px 边框适配要按 DPR 区间分层缩放,不能只判 2
很多方案只处理 DPR=2,但 iOS 13+ 的 iPad Pro、部分安卓旗舰已到 DPR=3,硬编码 transform: scale(.5) 在 DPR=3 下会变虚线或消失。
- DPR ≤ 1.49:不缩放,用原生
border - 1.5 ≤ DPR ≤ 2.49:
width: 200%; height: 200%; transform: scale(.5) - DPR ≥ 2.5:
width: 300%; height: 300%; transform: scale(.33333) - 所有伪元素必须设
pointer-events: none,否则遮挡点击 - 圆角要同步放大:
border-radius: $radius * 2,否则缩放后边缘露白
断点单位选 em 不是为“高级”,是为绕过 DPR 对 px 的干扰
iPhone Safari 把 @media (min-width: 480px) 解析为物理像素,而逻辑宽度只有 375px,结果横屏时断点失效。用 em(如 30em)基于根字号计算,不受 DPR 影响。
- 换算不能简单除以 16:
480px / 16 = 30em是理论值,实测应以浏览器渲染为准 - 根元素
html { font-size: 100% }必须固定,禁用 JS 动态改font-size,否则em断点基准漂移 - 避免
@media screen and (min-width: 48em)这种冗余写法,Sass 编译后就是@media (min-width: 48em),多写的screen and增加体积且无意义
最易忽略的是:Sass 所有 DPR 相关逻辑都在编译期固化,它无法感知用户是否开了系统缩放、是否横竖屏切换、是否插了外接显示器。真正可靠的适配,永远是 CSS 媒体查询 + HTML 视口配置 + 构建工具资源管理三者咬合,Sass 只负责把这套规则写得不重复、不手抖。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











