postcss-pxtorem仅构建时机械执行rem=px/rootValue除法,不读DOM或window;真机渲染正确性完全取决于JS设置的html font-size与rootValue严格一致,且JS须内联于head、监听resize/orientationchange并防抖。

根本不用“实现缩放”——postcss-pxtorem 不做缩放,它只做一次除法:rem = px / rootValue。真机上是否缩放、缩多少,全看 JS 设置的 document.documentElement.style.fontSize 和你配的 rootValue 是否严丝合缝。
rootValue 必须和 JS 设置的 font-size 完全相等
这是所有错乱的起点。插件构建时根本没 DOM,不读 window.innerWidth,不查 screen.width,只机械计算。你 JS 里写的是:
document.documentElement.style.fontSize = window.screen.width * window.devicePixelRatio / 10 + 'px'
那 rootValue 就得是 screen.width × dpr ÷ 10 的理论值(比如 iPhone 14 Pro:390 × 3 ÷ 10 = 117)。但更常见的是固定设计稿基准:
- 设计稿宽 750px →
rootValue: 75(对应 1rem = 75px) - 设计稿宽 375px →
rootValue: 37.5(对应 1rem = 37.5px) - 用了
amfe-flexible?它设的是clientWidth / 10,你就得配rootValue: 37.5(iPhone 6/7/8)或动态函数——但函数不能访问 window,只能按文件路径区分
JS 设置 font-size 必须在 内联执行
否则 CSS 已按错误 rootValue 转完,JS 才生效,页面先闪一下小字再拉大,或者直接失真。
- 把 JS 放进
里,用<script></script>标签包裹,不要 defer,不要 module - 监听
resize和orientationchange,但必须防抖:setTimeout(() => setRem(), 100),避免横竖屏切换时高频重设 - 别用
clientWidth(受滚动条、缩放、iframe 影响),改用window.screen.width * window.devicePixelRatio
border / box-shadow / 1px 默认不转,不是 bug 是保护
1px ÷ 75 = 0.013rem,在小屏上渲染就是 0。插件默认跳过 border、border-radius、box-shadow 等属性里的 px 值。
- 要转 border?明确写
propList: ['font-size', 'width', 'height', 'border'],别用['*'] - 想放开 1px?设
minPixelValue: 1,但务必配合selectorBlackList: [/^\.hairline/],让 .hairline 类自己控制 - box-shadow 强烈不建议转——阴影偏移和模糊半径转 rem 后极易糊成一片或消失
mediaQuery: true 是断点杀手,必须关掉
设成 true 后,@media (max-width: 768px) 会变成 @media (max-width: 20.48rem)。而 20.48rem 在 iPhone SE 上 ≈ 768px,在 iPad Pro 上 ≈ 2099px —— 断点彻底失效。
- 保持
mediaQuery: false(默认值) - 媒体查询逻辑交给 JS:监听屏幕变化后,动态加 class 到
,再用.mobile .btn这类选择器写样式 - 或断点仍用 px 写:
@media (max-width: 768px),不依赖 rem
最常被忽略的其实是 exclude:不排除 node_modules 和 UI 库(如 vant、element-plus),它们的 px 样式会被强行转 rem,导致按钮变小、图标错位。还有 replace: true 必须开,否则生成的是 width: 100px; width: 1.33333rem,老浏览器 fallback 失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











