<p>px是固定像素单位,无法适配不同DPR和屏幕宽度;rem是相对于根元素font-size的相对单位,需配合JS动态设置html字体大小才能实现等比缩放;SCSS中应定义带基准参数的px2rem函数(如@function px2rem($px, $base: 100) { @return ($px / $base) * 1rem; }),避免硬编码,并确保JS根字号设置与SCSS基准严格对齐。</p>

为什么直接用 px 在移动端会出问题
因为不同手机屏幕物理像素密度(dpr)和宽度差异大,px 是固定像素单位,写死后在 iPhone 14 Pro 和低端安卓机上实际显示大小可能差一倍。rem 是相对于根元素 font-size 的相对单位,配合动态设置 html 根字号,才能实现真正等比缩放。
SCSS 中怎么写一个可靠的 px2rem 函数
不能简单除以某个固定值(比如除以 37.5),因为设计稿基准、项目根字号策略、是否兼容 dpr 都会影响换算逻辑。函数得支持传参控制基准值,并默认适配主流 750px 设计稿 + 1rem = 100px 的常见方案(即 html { font-size: 100px } 时,1rem = 100px,100px 设计稿尺寸 → 1rem)。
实操建议:
- 定义函数:
@function px2rem($px, $base: 100) { @return ($px / $base) * 1rem; } - 调用时明确意图:
font-size: px2rem(32);→ 输出0.32rem;width: px2rem(750, 75);→ 输出10rem(适配 75px 基准) - 避免把
$base写成魔法数字,统一提成变量:$rem-base: 100;,函数里引用它 - 别在函数里做媒体查询或 JS 注入逻辑——那是运行时的事,SCSS 编译期只管静态换算
用 px2rem 后为什么某些元素还是没缩放
常见原因是:根元素 html 的 font-size 没动态设置,或者设置逻辑被覆盖。SCSS 函数只负责“写出来是多少 rem”,不负责“这个 rem 到底多大”。
立即学习“前端免费学习笔记(深入)”;
典型踩坑点:
- 忘记在 HTML 中注入 JS 动态根字号脚本,或脚本执行晚于 CSS 加载,导致初始渲染用的是浏览器默认 16px
- 写了
html { font-size: 50px; }这样的硬编码样式,覆盖了 JS 设置的值 - 使用了第三方 UI 库(如 vant),其内部样式用了
px或自己的 rem 基准,和你的$rem-base不一致 - 媒体查询里用了
px单位写断点(如@media (max-width: 750px)),应改用em或rem保持一致性
要不要用 PostCSS 插件替代 SCSS 函数
可以,但要看团队协作和构建链路。PostCSS 的 postcss-pxtorem 是运行时自动转换,写 16px 就输出 0.16rem,省去手动调用函数;但它无法处理计算式(如 calc(100px - 20px))、变量内插、或需要条件判断的场景。
选 SCSS 函数更可控的情形:
- 部分组件需保留
px(如 1px 边框,在高清屏下要结合transform: scaleY(0.5)) - 设计稿分两套(比如 H5 用 750px,小程序用 640px),需按上下文切换基准
- CI/CD 流程中禁止引入额外 PostCSS 插件,或已有复杂 PostCSS 配置怕冲突
真正难的不是写函数,是统一所有人对“1rem 等于多少设计稿像素”的理解,以及确保 JS 设置根字号的时机和容错逻辑到位。


















