移动端rem布局详解

1. rem是什么

rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。rem计算的规则是依赖根元素。

2. 基本写法

如下面定于的html的节点

1
2
3
4
5
6
7
8
html {
font-size: 10px;
}
.sonDom {
width: 6rem; //相当于6*10=60px
height: 3rem; //相当于3*10=30px
}

通过上面分析,我们可以得出可以通过改变html的font-size的值而等比改变所有用了rem单位的元素,而这个正是rem实现完美的分辨率适配的原理。


3. 如何动态更改根元素font-size的值

为了实现分辨率适配,我们需要用根据屏幕的大小动态去计算根元素的font-size的值,目前普遍的有两种方法:

1、通过媒体查询的方式,能够满足大部分场景,只需要把常用的屏宽度考虑进去即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*默认为20px*/
html {
font-size: 20px;
}
/*根据宽度设置不同的html font-size值去覆盖默认值*/
@media only screen and (min-width: 320px;){
html {
font-size: 10px;
}
}
@media only screen and (min-width: 375px;){
html {
font-size: 16px;
}
}
@media only screen and (min-width: 414px;){
html {
font-size: 20px;
}
}
2、通过js设置

如果希望把所有屏幕大小给考虑进去,可以考虑使用js来计算,如下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var doc = document,
win = window;
function initFontSize () {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function() {
var clientWidth = docEl.clientWidth; //window.innerWidth;
if(!clientWidth) return;
fontSizeRate = (clientWidth / 375)
var baseFontSize = 15 * fontSizeRate;
docEl.style.fontSize = baseFontSize + 'px';
};
recalc();
if(!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
}

4. rem换算

我们在开发的时候,往往不希望涉及到rem的换算,如一个设计稿按钮是120px,如果我们根节点font-size是14px,计算 120/14=8.571rem。感觉还是挺麻烦得,而这些工作是可以通过sass等预处理器或者构建去完成。

如下面翔神写的fis插件
https://github.com/imweb/fis-parser-rem


5. 效果图

效果图


6.rem需注意点

在移动端使用rem的话,兼容性是没问题的,但还是存在着一些需要注意的地方:

1、小数数值处理

不同浏览器计算rem转换为px数值时,对于小数点后的数值的处理是有所偏差,rem计算偏差的根源是浏览器内核数字类型的区别,如果浏览器的内核数字类型是float类型,能够较好地支持有小数点的数值。当浏览器内核数字类型是int类型,不支持小数点,会对数字进行四舍五入,这样就会有偏差。如果元素越大偏差得就越明显!

2、雪碧图rem

使用rem的同时又涉及到雪碧图时,由上面我们可以得知,rem的换算成px的尺寸非严格精确尺寸,如果雪碧图如果图标之间的距离过小,就可能导致图标过界,因此图与图之间的间隙需要留相应大一点。

3、单纯的rem没解决高度适配的问题

单纯的rem没解决高度适配的问题,当然目前也没有特别多高度适配的场景,因此建议如果需要在使用rem基础上还做相应的高度适配,就要通过相应的js去辅助啦。