核心是「开发写px、构建转rem、运行时动态设font-size」三者协同:rootValue必须与JS设置的html.fontSize基准严格一致,如750px设计稿配rootValue:75,JS计算fontSize=clientWidth/750*75,确保真机渲染不失真。

H5 移动端视口适配结合 postcss-pxtorem 实现自动化 px 转 rem,核心在于「开发写 px、构建自动转 rem、运行时动态控制根字体大小」三者协同。不需要手动计算,也不依赖运行时 JS 转换单位,关键在配置对齐与逻辑闭环。
动态根字体(font-size)必须与 postcss 配置一致
postcss-pxtorem 的 rootValue 参数,代表「1rem 等于多少 px」——这个值必须和 JS 运行时设置的 html.fontSize 基准完全对应。
常见设计稿宽度为 750px,推荐统一按以下方式设定:
-
rootValue: 75→ 表示 750px 设计稿下,1rem = 75px(即 10:1 比例) - JS 中计算
fontSize = clientWidth / 750 * 75,结果单位是 px
例如:iPhone SE(375px 宽)→375 / 750 * 75 = 37.5px→ 此时1rem = 37.5px
PostCSS 插件配置要点
在 postcss.config.js 或 Vite 的 css.postcss.plugins 中启用 postcss-pxtorem,关键项如下:
-
rootValue: 必须与 JS 中的基准值一致(如 75) -
unitPrecision: 推荐5,避免小数截断导致精度丢失 -
propList:['*']全局转换,但可排除min-width/max-width(加!前缀) -
exclude: 正则忽略node_modules和第三方 UI 库样式(如vant、nutui) -
minPixelValue: 设为2,防止 1px 边框被误转(保留物理像素)
JS 动态设置 html font-size
用轻量脚本监听 resize 和 pageshow(解决 iOS 缓存后 orientation 不触发问题),不依赖 lib-flexible:
function setRootFontSize() {
const baseWidth = 750;
const baseSize = 75;
const width = document.documentElement.clientWidth || window.innerWidth;
// 限制最大缩放(防 PC 端过大)
const scale = Math.min(width / baseWidth, 2);
document.documentElement.style.fontSize = baseSize * scale + 'px';
}
setRootFontSize();
window.addEventListener('resize', setRootFontSize);
window.addEventListener('pageshow', (e) => e.persisted && setRootFontSize());注意微信内置浏览器的大字体兼容
微信用户可能开启「系统大字体」,导致页面文字异常放大。需通过 WeixinJSBridge 主动禁用其默认缩放:
立即学习“前端免费学习笔记(深入)”;
if (typeof WeixinJSBridge === 'object' && typeof WeixinJSBridge.invoke === 'function') {
WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize': 0 });
}同时在 CSS 中对 .weui-cell__bd 等文本容器加 text-size-adjust: none(部分安卓也需)。
构建后验证是否生效
检查生成的 CSS 文件:
- 原
.btn { width: 160px; padding: 12px; } - 应转为
.btn { width: 2.13333rem; padding: 0.16rem; }(按 rootValue=75 计算)
若仍为 px,检查: - 是否在
vite.config.ts中正确引入插件(css.postcss.plugins) - 是否有
exclude错误匹配了当前文件路径 - 是否样式写在
<style>标签内但未被 PostCSS 处理(Vite 默认只处理.css/.scss/.less文件)
不复杂但容易忽略


















