小程序组件库用 px 还是 rpx?兼容性与选型指南
解释微信小程序 px 与 rpx 的换算规则、translateX 等场景的单位行为,并给出业务页面、自研组件库和第三方组件库的选型建议。
小程序组件库不需要在 px 和 rpx 之间二选一。更稳妥的默认方案是:用 rpx 表达随屏幕宽度变化的布局,用 px 表达不希望被大屏持续放大的尺寸,并把单位选择写进组件的设计约定。
不要对第三方组件库做全量 px -> rpx 转换。全量转换会同时改变边框、图标、弹层和内部定位,升级组件库时也更难判断差异。
先理解 px 和 rpx 的换算关系
微信小程序把屏幕宽度定义为 750rpx。换算关系是:
1rpx = windowWidth / 750 px
不同窗口宽度下,同一个 rpx 值对应不同的 CSS 像素:
| 窗口宽度 | 1rpx 对应的 px | 750rpx 的实际宽度 |
|---|---|---|
| 320px | 0.427px | 320px |
| 375px | 0.5px | 375px |
| 768px | 1.024px | 768px |
px 指 CSS 像素,不等于硬件面板上的单个物理像素。rpx 也不是更精细的像素单位,它只是按当前窗口宽度计算的相对长度。
这个换算方式适合手机上的等比布局,但在平板和桌面小程序窗口中会持续放大。组件库如果把高度、圆角、图标和字体全部写成 rpx,大屏上的控件可能显得过大。
按尺寸意图选择单位
单位选择应该由尺寸的用途决定:
| 场景 | 推荐单位 | 原因 |
|---|---|---|
| 页面栅格、左右留白、卡片宽度 | rpx |
需要跟随窗口宽度缩放 |
| 750 宽设计稿中的页面布局 | rpx |
标注值可以直接映射到布局值 |
| 细边框、分隔线 | px |
不需要随大屏持续变粗 |
| 最小点击高度、固定工具栏高度 | px 或受限尺寸 |
需要保持稳定的可用性边界 |
| 插画和大面积背景 | rpx、百分比 |
通常跟随容器或页面宽度变化 |
| 图标和文字 | 依据组件层级决定 | 页面展示可缩放,基础控件更适合受控尺寸 |
业务页面可以大量使用 rpx,因为页面通常直接对应设计稿。组件库需要覆盖手机、平板、分屏和不同业务密度,不能默认所有尺寸都按屏幕宽度线性增长。
对大屏适配要求较高时,可以组合相对尺寸和上限:
.page {
padding-inline: min(32rpx, 24px);
}
.card {
width: min(686rpx, 720px);
margin-inline: auto;
}
请先在目标微信基础库版本中验证 min() 等 CSS 函数的兼容性。如果项目需要覆盖较旧版本,可以在构建阶段生成等价样式或使用媒体查询。
translateX 可以使用 rpx
在 WXSS 中,transform 的长度值可以直接使用 rpx:
.panel {
transform: translateX(24rpx);
transition: transform 180ms ease;
}
.panel.is-open {
transform: translateX(0);
}
搜索中常见的疑问是 translateX 是否支持 rpx。只要位移写在 WXSS 中,浏览器样式解析会处理这个长度单位。
JavaScript 动画 API 接收数值时,不能假设这个数值也是 rpx。先按当前窗口宽度转成 px:
function rpxToPx(value) {
const { windowWidth } = wx.getWindowInfo();
return value * windowWidth / 750;
}
const animation = wx.createAnimation({ duration: 180 });
animation.translateX(rpxToPx(24)).step();
窗口尺寸可能在分屏、横竖屏切换或桌面环境中变化。不要在模块加载时永久缓存换算比例,应在创建动画或窗口变化后重新计算。
自研组件库要定义尺寸契约
自研组件库可以同时使用两类设计 token:
$space-page: 24rpx;
$control-height: 44px;
$hairline: 1px;
$dialog-width: 640rpx;
组件文档需要说明哪些值会随屏幕缩放,哪些值保持稳定。业务方覆盖样式时,只调整公开的 token 或样式接口,不直接覆盖组件内部选择器。
如果团队需要两套密度,可以在构建阶段生成 mobile 和 compact 变体。这里改变的是明确列出的 token,不是把产物中的每一个 px 批量替换成 rpx。
第三方组件库不要全量转换
第三方组件库已经基于自己的尺寸体系完成视觉和交互测试。PostCSS 对 node_modules 做全量换算会带来这些问题:
1px边框可能被转换并出现取整差异- 图标、遮罩、弹层定位和动画位移一起变化
- 组件文档中的尺寸与实际产物不再一致
- 升级后难以区分上游改动和本地转换结果
优先使用组件库公开的 CSS 变量、样式属性、主题配置或 wrapper 尺寸。确实需要转换时,只处理团队拥有的源码,并使用白名单明确转换目录和属性。
Taro、Mpx、uni-app 等框架都有自己的样式编译规则。项目应该只保留一条单位转换链路,并把输入单位、设计稿宽度、忽略规则写进构建配置。重复转换比不转换更难排查。
按项目类型做选择
可以用下面的决策表作为默认起点:
| 项目类型 | 默认策略 |
|---|---|
| 普通业务页面 | 布局使用 rpx,固定边界使用 px |
| 自研业务组件 | 通过 token 明确混合使用,不做隐式转换 |
| 跨业务组件库 | 以稳定尺寸为基础,为页面级间距开放 rpx token |
| 第三方组件库 | 保留原单位,通过公开接口适配 |
| Taro、Mpx、uni-app 项目 | 遵循框架编译配置,只转换自有源码 |
最后用真实设备和窗口尺寸验证,而不是只看 375px 的开发工具预览。至少覆盖一台窄屏手机、一台主流手机和一个平板或分屏窗口,并检查文字换行、点击区域、弹层定位和动画位移。
大型小程序还要把单位策略放进工程治理。滴滴出行项目使用 Mpx 处理多业务和构建问题,相关背景可以参考 大型小程序体积治理:滴滴出行的分包、依赖与架构取舍。
正在加载讨论...
讨论加载失败。 重新加载