uni.upx2px() 运行时按设备 screenWidht/750×rpx 计算像素值,H5 默认按375屏宽计算易出错;rpx 换算需匹配设计稿基准宽度,非750设计稿须换算;border、canvas、fixed等场景应避免直接用 rpx。

uni.upx2px() 在 JS 里转换 rpx 的真实行为
JS 里不能直接写 rpx,所有动态计算必须转成像素值才能参与逻辑(比如设置 transform: translateX()、计算滚动阈值、控制动画位移)。uni.upx2px() 就是干这事的——但它不是“静态换算”,而是运行时查当前设备屏幕宽度再算。
它内部等价于:Math.round(screenWidth / 750 * rpxValue),其中 screenWidth 来自 uni.getSystemInfoSync().screenWidth。注意:这个值是设备物理像素宽度(如 iPhone 13 是 390,不是 CSS 像素)。
- 在 H5 端,如果未配置
rpxCalculation,它默认按 375px 屏宽计算(哪怕你开着 1920px 宽的浏览器),这是最容易踩坑的地方 - App 端和小程序端通常更准,但某些安卓平板可能上报的
screenWidth不含状态栏,导致轻微偏差 - 不要在
onLoad之前调用,此时系统信息可能未就绪;稳妥做法是放在onReady或用uni.getSystemInfo异步兜底
rpx 在不同端的实际换算基准差异
rpx 的“750 份”是统一的,但每份对应多少物理像素,取决于各端如何取 screenWidth:
- 微信小程序:取
wx.getSystemInfoSync().screenWidth(单位 px),精确到设备原生分辨率 - App 端(iOS/Android):默认也取原生
screenWidth,但可通过manifest.json → "h5" → "rpxCalculation"强制设为固定值(如"375") - H5 端:默认强制按 375px 计算(即 1rpx = 0.5px),不管浏览器窗口多宽;想适配大屏需手动配置
rpxCalculation: "auto"并监听resize
这意味着:同一段 width: 375rpx 样式,在 iPhone 13(390px 宽)上渲染为 195px,在某安卓机(360px 宽)上是 180px,在 H5 默认模式下恒为 187.5px——差别虽小,但在做精确对齐或 canvas 绘图时会暴露。
设计稿宽度 ≠ 实际 rpx 换算起点
很多人以为“设计稿是 750px,所以直接写数字就行”,这没错;但若设计稿是 375px,就容易误算。关键不是设计稿本身,而是换算公式里的分母:
实际公式是:rpx 值 = 750 × (设计稿中元素宽度 px) ÷ (设计稿基准宽度 px)
- 设计稿宽 750px → 元素宽 100px → 写
100rpx - 设计稿宽 375px → 元素宽 100px → 写
200rpx(不是 100rpx!) - 设计稿宽 640px → 元素宽 100px → 写
117rpx(四舍五入)
漏掉除法这一步,是团队协作中最常见的样式错位根源。建议把换算逻辑封装成一个简单函数,避免手算出错。
什么时候坚决不能用 rpx
rpx 天然绑定屏幕宽度,所以任何“不希望随屏幕变宽而放大”的场景,都该避开它:
-
border: 1rpx solid #ccc—— 在 414px 宽手机上变成 0.55px 边框,极可能渲染为 0 或糊边;应改用border: 1px+transform: scaleY(0.5)模拟 0.5px - 图标字体大小(如 iconfont)—— 若用
font-size: 40rpx,横屏 iPad 上字体会巨大;更适合用rem或固定px - Canvas 绘图坐标系 ——
canvas.getContext('2d').fillRect(0, 0, 100, 100)里的 100 是像素,不是 rpx;传入uni.upx2px(100)才对 - Fixed 定位元素的偏移量(如底部 tabbar)—— 如果用
bottom: 100rpx,横屏时会往上浮,破坏锚点一致性
rpx 很好用,但它不是万能胶。真正决定适配质量的,是你清楚每一处尺寸背后依赖的是什么变量——宽度?DPR?还是用户缩放?


















