利用rem进行移动端适配

之前面试的时候被问到移动端适配用什么单位,答不出来,遂搜集了一些资料总结成这篇文章。水平有限,虽然已经尽可能地保证不出错,但难免有这样或那样的漏洞,如果你发现任何问题,请给我留言。感恩。

什么是rem?

一般来说我们听到更多的是em,而rem则是root em的意思。顾名思义,rem是指相对于根元素字体大小的单位,而这个根元素,一般指的就是html。例如,若html的font size为16px, 则1rem=16px。

兼容性

目前PC端的Chrome(4+),Firefox(3.6+),Safari(5+),以及IE(11+)均支持rem,移动端的主流浏览器,包括UC,QQ浏览器,三星内置浏览器也都支持rem。可以说只要不用支持古老的浏览器,如IE8、初代iPhone的Safari,都可以放心地使用rem。

优点

在说rem的优点之前我们先来回顾一下移动端适配的一般做法。

  1. 流式布局,宽度使用百分比定义,高度和文字大小用px固定。缺点是不同屏幕尺寸下显示效果会有差异,在大屏幕手机下甚至会因为元素宽度被过度拉伸导致显示效果不协调。因此仅适用于一些比较简单的页面。
  2. 固定宽度,给页面设置固定宽度,超出部分留白。很明显,这种粗暴的方法对大屏手机很不友好。
  3. 弹性盒子布局。
  4. 响应式布局,其实就是针对几个主流设置对应的CSS,再利用媒体查询(Media Queries)来确定需要显示的样式。当然这样要求我们写额外的样式,提高了工作量,同时由于不可能为所有屏幕尺寸写针对性的样式,因此只能在若干主流的屏幕尺寸下做到完美显示。

我们发现这些方法要么不能在不同设备上完美显示,要么就是过于复杂,而rem却能很好的兼顾简单和兼容性。

之前提到rem是相对于根元素字体大小的单位,如果根元素的font size是16px,那么1rem就是16px,如果根元素是37.5px,那么1rem就是37.5px。可见,如果页面元素都用rem来设置大小,那么我们只需要修改根元素的font size就能等比例地缩放整个页面。也就是说只要根据不同屏幕尺寸设置根元素font size,我们就能等比例适配所有屏幕,是不是很优雅?

用法

说了那么多我们来看看究竟要怎么使用吧。先看一个例子。

Demo

1
<div class="btn">button</div>

1
2
3
4
5
6
7
8
9
10
11
12
html{
font-size:40px;
}
.btn{
width: 2rem;
height: 0.5rem;
font-size: 0.5rem;
line-height: 0.5rem;
text-align:center;
background-color:red;
}

image

例子中div的单位都是rem,留意宽高,可以看到宽高分别是80px和10px,而这正分别等于 2*40px和0.5*40px。这表明宽高是通过根元素html的font-size计算出来的,此时1rem=40px。

此时我们把html的font-size修改成原来的两倍即80px,其他不作改动,结果如下图所示。
image
显然div的宽高也变成了原来的两倍,此时1rem=80px。这也印证了之前所说的只需通过修改根元素的font-size值就可以等比例缩放。

相信到这里大家也发现,每次设置rem都要换算一遍,非常麻烦。为了方便我们可以:

  1. 将根元素的font-size设置成100px,这样只需要将px的数字的小数点往前挪两位再把单位换成rem就可以了,例如160px换成rem就是1.6rem。
  2. 利用sass,less等css预处理语言,设置一个函数专门用于单位转换。由于各种语言实现有区别,这里就不给出例子了。
  3. 利用现成的转换工具,这里推荐一个在线转换工具: px–>rem

这篇文章的主题是移动端适配,现在就具体讲讲在实际运用中如何用rem适配不同大小的屏幕

一般来说我们拿到的设计稿都是以iphone6的屏幕为基准设计的,也就是说宽度为375px,假设我们把根元素的font-size设置为100px。如果我们要适配的屏幕宽度为320px(即iphone5的屏幕宽度),那么此时根元素font-size应该设置为:100*(320/375),即85.3px。通过这样设置我们的页面便能完美等比例适配320px的屏幕。

为了计算方便,也为了避免根元素的font-size太大我们一般把根元素font-size设置为屏幕宽度的1/10(即375px的屏幕就设置为37.5px,320px的屏幕就设置为32px)。这样我们无需经过计算就能直接根据需要适配的屏幕宽度来得出font-size的大小,同时也能避免根元素font-size太大。

现在问题来了学挖掘机哪家强 究竟怎么动态修改font-size呢?有一个简单粗暴地方法,既然主流的屏幕分辨率也就那几个,我们大可以通过media query媒体查询,把最常见的几种情况写下来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
html {
font-size : 37.5px;
}
@media only screen and (min-width: 320px){
html {
font-size: 32px !important;
}
}
@media only screen and (min-width: 414px){
html {
font-size: 41.4px !important;
}
}
}

这样基本能覆盖大部分设备了,如果说一定要适配所有设备,我们还可以通过JS动态计算font-size。淘宝的首页就是用这个方法,审查元素之后可以看到不断改变屏幕大小,html的font-size都能实时变化。

1
document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';

我们把上面的代码绑定到DOMContentLoaded时间中,这样在进入页面的时候就能马上计算出font-size。

参考资料:

http://www.alloyteam.com/2016/03/mobile-web-adaptation-tool-rem/

http://caibaojian.com/toutiao/6215

https://isux.tencent.com/web-app-rem.html