
引言
移动端适配中,rem 单位常被误用导致 UI 走样。十有八九是 px 写死或根字体计算错误。本文不整教科书废话,直接上干货,手把手教你把设计稿'焊'在屏幕上。
rem 单位解析
rem 与 em 的区别
em 是相对父元素,多层嵌套计算复杂。rem (root em) 只看根元素 html 的 font-size。理论上 1rem = 16px,但实际开发中 root 字体大小并非固定。
浏览器渲染机制
浏览器只认 viewport,受 dpr(设备像素比)影响。iPhone dpr 为 2 或 3,安卓机各异。部分国产安卓机会在系统设置里调大字体,导致 rem 布局爆炸。
核心变量关系
viewport、dpr、根字体三者配合不当是界面乱套的真凶。假设设计稿 750px,meta 标签如下:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
JS 动态设置根字体常见写法:
// 注意:需根据实际设计稿基准调整除数
document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';
若 iPhone 14 Pro viewport 宽度 393px,dpr 为 3,根字体变为 393/7.5 = 52.4px。设计稿 100px 按钮应为 1rem,实际渲染变小。部分安卓 webview 会缩放或注入 JS,导致计算混乱。
等比扩大核心逻辑
设计稿基准确认
设计稿宽 375 还是 750?先确认基准。
- 375px 基准:除以 7.5,
1rem = 50px。 - 750px 基准:除以 7.5,
1rem = 100px。
建议项目文档写死:'本项目以 iPhone 6/7/8 宽度 375px 为基准,1rem = 50px'。
动态设置函数
一个靠谱的 rem 适配方案核心代码如下:
(function(window, document){
docEl = .;
dpr = . || ;
(){
(.){
... = ( * dpr) + ;
} {
.(, setBodyFontSize);
}
}
();
(){
rem = docEl. / ;
rem = rem > ? : rem;
docEl.. = rem + ;
}
();
resizeTimer;
.(, (){
(resizeTimer);
resizeTimer = (setRemUnit, );
}, );
.(, (){
(setRemUnit, );
}, );
.(, (){
(e.){
();
}
}, );
(dpr >= ){
fakeBody = .();
testElement = .();
testElement.. = ;
fakeBody.(testElement);
docEl.(fakeBody);
(testElement. === ){
docEl..();
}
docEl.(fakeBody);
}
})(, );


