移动端的开发基本不多直接使用px做为单位了,目前最经常使用的是rem。不过在这以前其实还有个em单位,和rem长得很是的像,那么它们有什么区别呢?又有什么不同的适用场景呢?javascript
注意:不管使用em,仍是rem,客户端最终解析的值依旧是px!
从title的解释就能够看出,em的基准是其父级元素,不过这个父级元素要求是设置有font-size值的,以下面的例子:css
<div class="father" style="font-size:20px;"> <div class="son" style="font-size:2em;"></div> </div>
那么son的字体大小就是2 * 20px = 40px,此时,若是father的字体大小变化了,那么son的也会跟着变化。假如没有父元素,则基准就是body(因为默认浏览器默认字体为16px,因此默认状况1em=16px)。html
跟上面解释body基准时的差很少,默认状况下1rem=16px。此时,只要根元素字体大小不变,那么相对于它的rem就不会变。
对于移动端的各类机型来说,因为不一样的机型屏幕尺寸、分辨率都不同,不太可能使用相同的根元素字体大小做为基准,因此所谓rem布局,就是经过js动态计算出不一样机型的根元素字体大小值,来对页面进行等比例的缩放,达到适配大部分机型的效果。
那么具体如何去设定这个基准呢?
假设把手机屏幕宽度均分红10等份(由于rem布局就是针对宽度去作设定的),规定其中的一份做为根元素的font-size值,那么根元素font-size值就可由下述公式得到:前端
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
在这个基准下,那么1rem的值也随之获得了:java
1rem = document.documentElementstyle..fontSize = document.documentElement.clientWidth / 10 + 'px';
那么,不一样屏幕的机型因为屏幕宽度不一样,也就获得了在"屏幕宽度均分红10等份"这个标准下的rem相对值。比较完整的计算方式以下:git
// set 1rem = viewWidth / 10 function setRemUnit () { var rem = docEl.clientWidth / 10 docEl.style.fontSize = rem + 'px' } setRemUnit() // reset rem unit on page resize window.addEventListener('resize', setRemUnit) window.addEventListener('pageshow', function (e) { if (e.persisted) { setRemUnit() } })
注意:这里的标准 "10"能够是任一值,只要跟下面转换公式中用到的标准值保持一致便可,这里只是为了计算方便才这么设定。
这样,rem的基础生态就搭建好了。那么如何基于这套标准应用到开发中去呢?github
在继续以前,先来了解下"像素"这个知识点,由于接下来都会用到它的概念。
像素分为两种:设备像素和CSS像素
一、设备像素(device independent pixels): 设备屏幕的物理像素,任何设备的物理像素的数量都是固定的
二、CSS像素(CSS pixels): 又称为逻辑像素,是为web开发者创造的,在CSS和javascript中使用的一个抽象的层
在pc端,css像素和物理像素是1:1的关系;而在移动端,因为相似retina的各类高清屏的出现,css像素和物理像素的关系通常是1:2或者1:3,即1个css像素容纳2到3个物理像素,实现高清的效果。
通常移动端页面的开发流程是:设计人员以某个机型做为标准,设计好UI。前端开发针对这个机型的UI作开发,而后其它机型相对的去等比例缩放。
这里以iphone6做为标准(由于实际开发中基本也是用它作设计),它的物理像素为750x1334,css像素为375*667,假设UI上图片a的宽度为140,那么如何把它转换成以rem为单位的值呢?
如今屏幕宽度是已知的10rem,要求UI上宽140的rem值,假设为X,由下图能够很容易的获得比例关系:web
屏幕宽度/UI宽度 = x/140 = 10rem / 750 =》 x = 140 / 750 * 10 rem
通常能够在sass中经过封装预处理函数进行这个转换过程:编程
$UI_WIDTH: 750; @function px2rem($px) { @return ${ $px / $UI_WIDTH * 10 }rem; //=>or @return ${ $px / 75 }rem; } img{ width: px2rem(140); }
这就是"rem布局"原理的整个实现过程!浏览器
而随着社区各类工具的完善,如今也无需手动去使用如px2rem的这种预处理函数去转换,比较流行的作法是使用postcss的postcss-px2rem插件去自动处理,开发时仍然按照px的方式去编程,postcss配置例:
postcss: function() { return [px2rem({remUnit: 75})]; //设置基准值,75是以iphone6的标准 }
这里的remUnit设置是有必定规则的,好比屏幕宽度等分红10份,当UI以iphone6(即物理像素宽度750)设计时,remUnit=75;当UI以iphone5(即物理像素宽度640)设计时,remUnit=64。能够看出它中遵循以下公式:
remUnit = 物理像素宽度 / 设定的屏幕宽度等分值;
至于具体的js等分逻辑封装能够参看手淘的flexible。
那么在实际开发中,究竟适用em仍是rem呢?记住以下原则便可:
本文收录在我的的Github上 https://github.com/kekobin/bl... ,以为有帮助的,欢迎start哈。支持原创,未经本人赞成,请勿转载!