移动端rem适配需用screen.width/devicePixelRatio算CSS像素宽再按设计稿比例换算根字号,监听resize和orientationchange,全局设box-sizing:border-box,viewport必须写全且禁缩放,flex与rem混用需避精度误差。

rem单位怎么设根字体大小才不翻车
移动端用rem本质是靠动态改html的font-size来缩放整个布局,但很多人直接写document.documentElement.style.fontSize = window.innerWidth / 375 * 16 + 'px',结果在iPad、折叠屏或横屏下错乱——因为window.innerWidth返回的是视口宽度(可能含滚动条),不是设备逻辑像素宽度,更不是设计稿基准宽。
- 优先用
window.screen.width(设备物理像素宽)除以设备像素比window.devicePixelRatio,得到CSS像素宽,再按设计稿比例换算(比如375px设计稿就除以375) - 必须监听
resize和orientationchange,横竖屏切换时视口尺寸突变,不重算font-size会导致文字突然撑开或压缩 - 避免在
body上设min-width或max-width,它会干扰rem缩放后的实际渲染宽度
box-sizing: border-box为什么在rem布局里更关键
默认box-sizing: content-box会让padding和border额外增加元素总宽,而rem值通常来自设计稿的“整体尺寸”,设计师给的按钮高44px,指的是包含内边距和边框的总高。如果没统一设box-sizing,你写height: 2.75rem(假设1rem=16px),实际内容区只剩不到40px,按钮看起来就被“削薄”了。
- 全局加
* { box-sizing: border-box },别漏掉伪元素::before/::after - 第三方UI库(如vant、nutui)内部可能覆盖
box-sizing,需单独重置其组件的box-sizing - 慎用
transform: scale()模拟缩放——它不触发重排,但会模糊文字、影响点击热区,且和rem混用时尺寸计算完全失控
viewport meta标签配错,rem直接失效
rem生效的前提是页面真实按设备逻辑像素渲染。如果viewport写成width=device-width, initial-scale=1.0但没加maximum-scale=1.0,iOS双击放大后视口缩放值变化,html根字号不变,所有rem元素就集体“失重”——看着小,点不中,表单输入框光标错位。
- 必须写全:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> - 不要用
width=375这种固定值,它在非375px宽设备上强制缩放,让rem计算失去意义 - 某些安卓WebView(尤其旧版)忽略
viewport,得配合document.documentElement.style.width = '100%'兜底
flex布局和rem混用时的常见错位
用flex做等分布局(比如三列图标),每列设flex: 1再套rem内边距,看似合理,实则危险:当父容器宽度不能被整除时,浏览器对flex剩余空间的分配精度只有0.1px,而rem换算后常带小数(如1.25rem = 20px),两者叠加导致列宽出现1px偏差,视觉上明显不齐。
立即学习“前端免费学习笔记(深入)”;
- 等分容器优先用
flex-basis代替flex: 1,例如flex: 0 0 calc(33.333% - 2rem)(减去左右padding) - 涉及
gap属性时,别用rem值——gap不支持rem在部分老Android WebView中回退为0 - 图片用
rem设宽高时,记得加height: auto,否则拉伸变形;若需等比缩放,用aspect-ratio而非padding-top百分比
rem适配真正难的不是计算公式,而是每个环节都依赖上游参数稳定:viewport不准,根字号就飘;box-sizing不统,尺寸就虚;flex和rem一碰,像素就打架。这些地方松动一点,整个布局就从边缘开始崩。


















