以前发过一篇文章《移动端应该如何动态设置字体大小?》,主要说了移动web端布局的一些解决方法,本文再一次把这个问题提出来,并分别对安卓和IOS设备的屏幕了解作出本身的分享,在进入正文以前最好先了解:物理像素、逻辑像素、DPR和Rem。html
那么进入正文,不废话,直接把本身了解到的和一些见解说出来。android
首先是屏幕问题,如今主流的移动设备以安卓和IOS为主,咱们在制做移动端页面也是以兼容这两种设备去布局。git
首先说iPhone,不得不说iPhone的屏幕考虑到了咱们开发者的难处,从而给出iPhone屏幕的dpr都是整数值,在6plus出现以前,iphone的dpr始终是2(物理像素/逻辑像素=2),即便是6plus出现了,iphone到底其实也就只有2,3这两个dpr。其实6plus的实际dpr并非整数,而是2.87左右,不过,为了方便开发者来开发,iphone6plus对其作了一个调整,将dpr调整为3,而后在对屏幕进行了一个缩放。因此咱们很容易对其作到兼顾。github
而安卓的dpr值,并不像iphone那样就只有两个值。安卓的dpr是千奇百怪的,多是1.5,2,3,4,2.5等等的都有。(甚至我还看到了1.7之类的,安卓的各个设备商,玩的真尼玛high啊。怎么高兴怎么来。)web
那么如今开始说说移动端怎么布局以及字体该怎么设置,由于有各类各样的解决方式,我就不一一赘述,直接说手淘的解决方案:flexible.jssegmentfault
我为何又一次把这个拿出来讲,主要有两点缘由:1.我以为它好用,解决方式简单粗暴。2.它通过了比较长时间的考验,现在手淘还在用它。app
具体的使用方法本身能够去flexible.js看看,这里我简单说说它的方案以及我的对它的改良。iphone
咱们UI在制做移动端页面时,主流的宽度有640、750或者还有其余尺寸,这里咱们用640作为例子,那么手淘的作法就是将640的宽度分为10份,每份是64,那么1个rem=64px,也就是说此时 html{font-size:64px;}
,好比设计稿中有个元素宽64px,高128px,那么这个div的宽用rem表示就是:64(设计稿元素的宽)/64(1rem为64px)=该元素计算出的rem值
,同理高度从px换成rem就是128/64=2rem
样式就是div{width:1rem;height:2rem;}
。而后再配上flexible.js的代码段:布局
function refreshRem(){ var width = docEl.getBoundingClientRect().width; if (width / dpr > 540) { width = 540 * dpr; } var rem = width / 10;//看到了吗 看到了吗 这句话 分红10份哦 docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem; }
对于布局,咱们可使用rem去结局,那么字体呢?字体
你们知道,如今PC端主流的字体大小都是相似12px、14px、16px,几乎没有1三、1五、17这样的数字出现,至于为何,请进穿越门了解。若是咱们用rem作为字体单位,那么转成px的时候,势必会出现奇数或者小数的状况,为了不这种状况,咱们仍是要用px作为字体的单位。那么又如何用px去看成字体大小呢?
首先看这段代码:
div { width: 1rem; height: 0.4rem; font-size: 12px; // 默认写上dpr为1的fontSize } [data-dpr="2"] div { font-size: 24px; } [data-dpr="3"] div { font-size: 36px; }
没有错,手淘的解决方案就是默认写个dpr为1时的字体大小,而后根据不一样dpr下的值去匹配不一样的字体大小。
flexible会获取设备的dpr值,而后在html标签上自定义data-dpr属性,并放入dpr值,后面的font-size就是动态设置一个rem单位的大小。
其实我以为这种方案挺恶心的,每一个牵扯到字体的大小就必须多些几套去兼容,但这也算是个方案。
最后就是对flexible.js的见解,话很少说上代码:
if (!dpr && !scale) { var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; if (isIPhone) {//只对iPhone作了处理!!!! // iOS下,对于2和3的屏,用2倍的方案,其他的用1倍方案 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其余设备下,仍旧使用1倍的方案 dpr = 1; } scale = 1 / dpr; }
能够看出,flexible中动态设置dpr时,只对iPhone进行了处理,彻底没有把安卓放在眼里,那安卓怎么办?这里我又想吐槽安卓那些厂商,真尼玛瞎搞,dpr设置成各类非主流数值,玩死咱们这些码农了,连flexible都不想管了。吐槽到此为止,那么该怎么改良它,让它能对安卓手机也能动态设置dpr呢?咱们将这段代码改一下:
if (!dpr && !scale) { //devicePixelRatio这个属性是能够获取到设备的dpr var devicePixelRatio = win.devicePixelRatio; //判断dpr是否为整数 var isRegularDpr = devicePixelRatio.toString().match(/^[1-9]\d*$/g) if (isRegularDpr) { // 对因而整数的dpr,对dpr进行操做 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 对于其余的dpr,人采用dpr为1的方案 dpr = 1; } scale = 1 / dpr; }
咱们对这里作了一点点修改,即来判断dpr是不是规则的,也就是是不是咱们常见的1,2,3等,而后,咱们只对规则的dpr,来进行一个字体的处理。这样,iphone依然仍是用以前的匹配方案。而其实目前安卓,不少的设备仍是比较常见的dpr了,因此咱们这里,将以前对设备的判断,转变成对dpr是不是整数的一个判断。其余地方不变,能够解决对安卓dpr的部分匹配。