移动 Web 适配利器:rem

提到rem,你们首先会想到的是em,px,pt这类的词语,大多数人眼中这些单位是用于设置字体的大小的,没错这的确是用来设置字体大小的,可是对于rem来讲它能够用来作移动端的响应式适配哦。javascript

兼容性css

先看看兼容性,关于移动端html

  • ios:6.1系统以上都支持前端

  • android:2.1系统以上都支持java

大部分主流浏览器都支持,能够安心的往下看了。android

rem设置字体大小ios

rem是(font size of the root element),官方解释css3

意思就是根据网页的根元素来设置字体大小,和em(font size of the element)的区别是,em是根据其父元素的字体大小来设置,而rem是根据网页的跟元素(html)来设置字体大小的,举一个简单的例子,web

如今大部分浏览器IE9+,FirefoxChromeSafariOpera ,若是咱们不修改相关的字体配置,都是默认显示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屏幕适配以前,先说一下通常作移动端适配的方法,通常能够分为:

  1. 简单一点的页面,通常高度直接设置成固定值,宽度通常撑满整个屏幕。

  2. 稍复杂一些的是利用百分比设置元素的大小来进行适配,或者利用flex等css去设置一些须要定制的宽度。

  3. 再复杂一些的响应式页面,须要利用css3media 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实际上是根据咱们所拿到的视觉稿来决定的,主要有如下几点缘由:

  1. 因为咱们所写出的页面是要在不一样的屏幕大小设备上运行的

  2. 因此咱们在写样式的时候必需要先以一个肯定的屏幕来做为参考,这个就由咱们拿到的视觉稿来定

  3. 假如咱们拿到的视觉稿是以iphone6的屏幕为基准设计的

  4. 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事件来达到变化时更新htmlfont-size。

rem适配进阶

咱们知道,通常咱们获取到的视觉稿大部分是iphone6的,因此咱们看到的尺寸通常是双倍大小的,在使用rem以前,咱们通常会自觉的将标注/2,其实这也并没有道理,可是当咱们配合rem使用时,彻底能够按照视觉稿上的尺寸来设置。

设计给的稿子双倍的缘由是iphone6这种屏幕属于高清屏,也便是设备像素比(device pixel ratio)dpr比较大,因此显示的像素较为清晰。

通常手机的dpr是1,iphone4iphone5这种高清屏是2,iphone6s plus这种高清屏是3,能够经过js的window.devicePixelRatio获取到当前设备的dpr,因此iphone6给的视觉稿大小是(*2)750×1334了。

拿到了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');

设置完以后配合rem,修改

@function px2rem($px){ $rem : 75px; @return ($px/$rem) + rem; }

双倍75,这样就能够彻底按照视觉稿上的尺寸来了。不用在/2了,这样作的好处是:

  1. 解决了图片高清问题。

  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值,由于缩放可能会致使图片压缩变形等。

相关文章
相关标签/搜索