提到rem,你们首先会想到的是em,px,pt这类的词语,大多数人眼中这些单位是用于设置字体的大小的,没错这的确是用来设置字体大小的,可是对于rem来讲它能够用来作移动端的响应式适配哦。javascript
兼容性css
先看看兼容性,关于移动端html
大部分主流浏览器都支持,能够安心的往下看了。android
rem设置字体大小ios
rem是(font size of the root element),官方解释css3
意思就是根据网页的根元素来设置字体大小,和em(font size of the element)的区别是,em是根据其父元素的字体大小来设置,而rem是根据网页的跟元素(html)来设置字体大小的,举一个简单的例子,web
如今大部分浏览器IE9+,Firefox、Chrome、Safari、Opera ,若是咱们不修改相关的字体配置,都是默认显示font-size是16px即chrome
html { font-size:16px; }
那么若是咱们想给一个P标签设置12px的字体大小那么用rem来写就是
p { font-size: 0.75rem; //12÷16=0.75(rem) }
基本上使用rem这个单位来设置字体大小基本上是这个套路,好处是假如用户本身修改了浏览器的默认字体大小,那么使用rem时就能够根据用户的调整的大小来显示了。可是rem不只能够适用于字体,一样能够用于width height margin这些样式的单位。下面来具体说一下
rem进行屏幕适配
在讲rem屏幕适配以前,先说一下通常作移动端适配的方法,通常能够分为:
简单一点的页面,通常高度直接设置成固定值,宽度通常撑满整个屏幕。
稍复杂一些的是利用百分比设置元素的大小来进行适配,或者利用flex等css去设置一些须要定制的宽度。
再复杂一些的响应式页面,须要利用css3的media query属性来进行适配,大体思路是根据屏幕不一样大小,来设置对应的css样式。
上面的一些方法,其实也能够解决屏幕适配等问题,可是既然出来的rem这个新东西,也必定能兼顾到这些方面,下面具体使用rem:
rem适配
先看一个简单的例子:
.con { width: 10rem; height: 10rem; }
这是一个div,宽度和高度都用rem来设置了,在浏览器里面是这样显示的,能够看到,在浏览器里面width和height分别是160px,正好是16px * 10,那么若是将html根元素的默认font-size修改一下呢?
html { font-size: 17px; } .con { width: 10rem; height: 10rem; }
再来看看结果:
这时width和height都是170px,这就说明了将rem应用与width和height时,一样适用rem的特性,根据根元素的font-size值来改变自身的值,由此咱们应该能够联想到咱们能够给html设定不一样的值,从而达到咱们css样式中的适配效果。
rem数值计算
若是利用rem来设置css的值,通常要经过一层计算才行,好比若是要设置一个长宽为100px的div,那么就须要计算出100px对应的rem值是 100 / 16 =6.25rem,这在咱们写css中,其实算比较繁琐的一步操做了。
对于没有使用sass的工程:
为了方便起见,能够将html的font-size设置成100px,这样在写单位时,直接将数值除以100在加上rem的单位就能够了。
对于使用sass的工程:
前端构建中,彻底能够利用scss来解决这个问题,例如咱们能够写一个scss的function px2rem即:
@function px2rem($px){ $rem : 37.5px; @return ($px/$rem) + rem; }
这样,当咱们写具体数值的时候就能够写成:
height: px2rem(90px); width: px2rem(90px);;
看到这里,你可能会发现一些不理解的地方,就是上面那个rem:37.5px是怎么来的,正常状况下不是默认的16px么,这个其实就是页面的基准值,和html的font-size有关。
rem基准值计算
关于rem的基准值,也就是上面那个37.5px实际上是根据咱们所拿到的视觉稿来决定的,主要有如下几点缘由:
因为咱们所写出的页面是要在不一样的屏幕大小设备上运行的
因此咱们在写样式的时候必需要先以一个肯定的屏幕来做为参考,这个就由咱们拿到的视觉稿来定
假如咱们拿到的视觉稿是以iphone6的屏幕为基准设计的
iPhone6的屏幕大小是375px,
rem = window.innerWidth / 10
这样计算出来的rem基准值就是37.5(iphone6的视觉稿),这里为何要除以10呢,其实这个值是随便定义的,由于不想让html的font-size太大,固然也能够选择不除,只要在后面动态js计算时保证同样的值就能够,在这里列举一下其余手机的
iphone3gs: 320px / 10 = 32px
iphone4/5: 320px / 10 = 32px
iphone6: 375px / 10 =37.5px
动态设置html的font-size
如今关键问题来了,咱们该如何经过不一样的屏幕去动态设置html的font-size呢,这里通常分为两种办法
1利用css的media query来设置即
@media (min-device-width : 375px) and (max-device-width : 667px) and (-webkit-min-device-pixel-ratio : 2){ html{font-size: 37.5px;} }
2利用javascript来动态设置根据咱们以前算出的基准值,咱们能够利用js动态算出当前屏幕所适配的font-size即:
document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
而后咱们看一下以前那个demo展现的效果
.con { width: px2rem(200px); height: px2rem(200px); } document.addEventListener('DOMContentLoaded', function(e) { document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px'; }, false);
iPhone6下,正常显示200px
在iphone4下,显示169px
因而可知咱们能够经过设置不一样的html基础值来达到在不一样页面适配的目的,固然在使用js来设置时,须要绑定页面的resize事件来达到变化时更新html的font-size。
rem适配进阶
咱们知道,通常咱们获取到的视觉稿大部分是iphone6的,因此咱们看到的尺寸通常是双倍大小的,在使用rem以前,咱们通常会自觉的将标注/2,其实这也并没有道理,可是当咱们配合rem使用时,彻底能够按照视觉稿上的尺寸来设置。
1 设计给的稿子双倍的缘由是iphone6这种屏幕属于高清屏,也便是设备像素比(device pixel ratio)dpr比较大,因此显示的像素较为清晰。
2 通常手机的dpr是1,iphone4,iphone5这种高清屏是2,iphone6s plus这种高清屏是3,能够经过js的window.devicePixelRatio获取到当前设备的dpr,因此iphone6给的视觉稿大小是(*2)750×1334了。
3 拿到了dpr以后,咱们就能够在viewport meta头里,取消让浏览器自动缩放页面,而本身去设置viewport的content例如(这里之因此要设置viewport是由于咱们要实现border1px的效果,加入我给border设置了1px,在scale的影响下,高清屏中就会显示成0.5px的效果)
meta.setAttribute('content', 'initial-scale=' + 1/dpr + ', maximum-scale=' +1/dpr + ', minimum-scale=' + 1/dpr + ', user-scalable=no');
4 设置完以后配合rem,修改
@function px2rem($px){ $rem : 75px; @return ($px/$rem) + rem; }
双倍75,这样就能够彻底按照视觉稿上的尺寸来了。不用在/2了,这样作的好处是:
解决了图片高清问题。
解决了border 1px问题(咱们设置的1px,在iphone上,因为viewport的scale是0.5,因此就天然缩放成0.5px)
在iphone6下的例子:
咱们使用动态设置viewport,在iphone6下,scale会被设置成1/2即0.5,其余手机是1/1即1.
咱们的css代码,注意这里设置了1px的边框
.con { margin-top: 200px; width: 5.3rem; height: 5.3rem; border-top:1px solid #000; }
在iphone6下的显示:
在android下的显示:
rem进行屏幕适配总结
下面这个网址是针对rem来写的一个简单的demo页面,你们能够在不一样的手机上看一下效果
可是rem也并非万能的,下面也有一些场景是不适于使用rem的
1当用做图片或者一些不能缩放的展现时,必需要使用固定的px值,由于缩放可能会致使图片压缩变形等。