6

两个门派

根据屏幕宽度设置 rem

计算方式:
rem 根据屏幕宽度计算:屏幕宽度越大,元素的尺寸越大。

可以把网页想象成一张等比缩放的图片,当你屏幕宽度增大,图片被拉宽,同时高度也会等比例增长。
以iPhone6为例,假设1rem = 100px, 一个宽度 100px 的 div 在 iPhone6 (750px)下就是 1rem,iPhone6plus (828px)下就是 1rem = 110px;

这个门派细分的话还有两个分支,我们分别以网易和手淘为例

不设置viewpoint

参考网易:
iPhone6(2dpr)和iPhone6plus(3dpr)的宽度下,两者1rem分别为50px和55.2px,两者比例为 750 / 828 ,dpr没有参与计算;head中的viewport缩放一直是1。
具体来看 rem 的使用

clipboard.png

clipboard.png

上图中的图片元素的高度设置为1.4rem,可知其在设计稿中的高度为140px,那为什么实际显示为 70px 呢?其实仔细一看,html 元素的 font-size 被设置成了 50px !那为什么html上的font-size是50px呢?我的理解是:因为设计稿是2倍图,实际高度要除以2才行,高度为140px 的元素,其实要写成 .7rem,但每次计算样式都要除以2,太麻烦了,换个思路,如果直接将 rem 除以 2,那么计算尺寸时,只需要除以 100 即可,一劳永逸,提高了开发效率

设置viewport

参考手淘:

  • iPhone6 下,1rem = 75px;clipboard.png
  • iPhone6plus 下,1rem = 124.2px。 750 (828 / 750) = 82.8px,再根据dpr缩放,82.8px (3/2) = 124.2px。

为什么82.8px还要乘以1.5呢?因为手淘在viewport上面做了处理,页面整体缩小为i6尺寸的2/3,因此需要在单位尺寸上增加等比例的大小。

在写样式的时候,PS上量出的尺寸除以75。。。

还有坑爹的地方是,字体大小font-size一般情况下不适合跟随宽度缩放,可能只能写媒体查询。

网易和淘宝两者共同之处

两者都有一个共同的特点:可以把rem当作类似vw来用,因为他们都把宽度等分了。

  • 网易:i6下,1rem = 100px ,7.5rem = 750px; 分了7.5份。
  • 手淘:i6下,1rem = 75px,10rem = 750px;分了10份;

字体不适合使用rem计算

不同点:

  • 网易的方法比较便于计算,淘宝复杂一些。
  • 网易的适配在添加第三方插件的时候,相对方便,淘宝因为全局缩放,会影响第三方插件的样式。
  • 淘宝的方法可以轻松实现1px border,而网易需要特殊处理。

整合两者?

目的:方便计算 + viewprot缩放

在网易的基础上改进计算方法:

  • i6下,1rem等于100px,viewport缩放0.5;
  • 6p下,由于宽度变大:100px 1.104 = 110.4px;又有viewpoint缩放:110.4px 1.5 = 165.6px,1rem = 165.6px;

例子:

点我

clipboard.png

clipboard.png

根据 DPR 设置 rem

计算方式:
dpr越大,手机的屏幕越大,看到的范围越广,尺寸和dpr相关。

一般情况下dpr和 rem 的关系为:

  • dpr1 ==> 50px
  • dpr2 ==> 100px
  • dpr3 ==> 150px

例子中的代码来理解

dpr = 2时:
clipboard.png

dpr = 3时:

clipboard.png

总结


var dpr, rem, scale;
var docEl = document.documentElement;
var fontEl = document.createElement('style');
var metaEl = document.querySelector('meta[name="viewport"]');

dpr = window.devicePixelRatio || 1;

//IP6的设计稿,rem=100px,dpr=2,缩放0.5;
rem = 100 * dpr / 2;


//rem = docEl.clientWidth * dpr / 10;
//rem = docEl.clientWidth / 6.4; //相对于640  100px
scale = 1 / dpr;

// 设置viewport,进行缩放,达到高清效果,  iphone6为例  物理像素750 css像素375,将视口宽度设置两倍,在缩小
metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');

// 设置data-dpr属性,留作的css hack之用
docEl.setAttribute('data-dpr', dpr);

// 动态写入样式
docEl.firstElementChild.appendChild(fontEl);
fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}';

// 给js调用的,某一dpr下rem和px之间的转换函数
window.rem2px = function (v) {
    v = parseFloat(v);
    return v * rem;
};
window.px2rem = function (v) {
    v = parseFloat(v);
    return v / rem;
};

window.dpr = dpr;
window.rem = rem;

Larry_
704 声望186 粉丝

FE