初次接触移动端的时候,以为终于可以不用像pc那样考虑令人头疼的ie浏览器兼容问题,有强大的css3的帮助,可以随心所欲。。可是后来才发现原来移动端各种层次不齐的终端更会让人抓耳挠腮,同样的页面在不同的手机上显示的完全不一样的效果,于是抛开功能,页面适配性也成了一个大的课题。
说到移动端,下面这一行代码大家一定不陌生:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
如果对viewport还有不理解的可以直接去百度有很多资料,其中,device-width指设备的物理宽度,比如iphone4为320,剩下的initial-scale与maximum-scale指页面缩放值及最大缩放值,user-scalable表示是否允许缩放。
注意device-width并不等于手机的物理像素,同样宽度的屏幕物理像素可能为320,640,这就是我们常说的retina屏。当然也就意味着我们css中的1px可能是1个物理像素,也可能是2个物理像素,当然就显示来说我们设置1px的border不管是在哪个屏幕下看起来都是显示1px的。
移动端适配的解决方案大概有几种,现就我所了解的主要方法做个简单总结:
一.媒体查询
相信对响应式网站了解的同学都看过下面的写法:
@media screen and (max- 300px){
….
}
通过css3的媒体查询,我们可以对不同的分辨率设定不同的样式,如320px(device-width)下字号14px,而375px字号设为16px,等等。
这样我们就可以做到简单的适配,不过现在市场机型320,360,375等等各种分辨率,如果我们每一个都去U针对的话,代码量抛开不说,各种计算也会使得效率极其低下。
二.动态改变缩放值
1 var sW=$(window).width(); 2 3 if(sW>=640&&sW<720){ 4 5 $("#screeMeta").attr("content","width=640, initial-scale=1,minimum-scale=0.5, maximum-scale=0.5"); 6 7 }else if(sW>=720&&sW<750){ 8 9 $("#screeMeta").attr("content","width=640, initial-scale=1,minimum-scale=0.5, maximum-scale=0.56"); 10 11 }else if((sW>=750&&sW<800)){ 12 13 $("#screeMeta").attr("content","width=640, initial-scale=1,minimum-scale=0.5, maximum-scale=0.58"); 14 15 }else if(sW>=800&&sW<1000){ 16 17 $("#screeMeta").attr("content","width=640, initial-scale=1,minimum-scale=0.5, maximum-scale=0.65"); 18 19 }
基本思想为以640为基准,当在标准iphone4的时候页面整体缩放0.5,然后再遇到不同分辨率的时候赋予不同的缩放值,例如对于device-width为375的情况下,最大缩放值设为375/320*0.5。
这种方法的优点是我们可以完全按照设计稿来设定css尺寸,通过js的计算来实现不同机型的适配。当然缺点就是你当我们嵌入第三方页面或者将我们的页面嵌入第三方时,由于缩放值的不同会出现兼容性问题。
三.rem自适应
我们都知道rem不同于em相对于父元素的字体,rem是相对于html根字体来设置的,也就是假设html字体设为16px,那么设置为1rem的元素不论父级元素是哪一层都相当于设置了字体font-size:16px,我们来看一看淘宝和网易的页面:
iphone4:font-size设为64px,缩放值为0.5
iphone6:font-size设为75px,缩放值为0.5
我们再来看下元素设置:
除字体外,其他单位都用rem,这样通过动态的计算html的px,页面内容也会做相应比例的变化,字体用px显示。当然,他们的理念是大屏就要显示更多的字体。
关于字体有一个疑问始终没有搞明白,看下面几个图:
data-dpr=1,安卓机,字体设为12px,缩放值为1
data-dpr=2,iphone6,字体设为24px,缩放值为0.5
data-dpr=3,iphone6 plus,字体设为36px,缩放值为0.333
看上面3个截图,可以看到,通过不同的dpr,为html赋予了不同的data-dpr属性,然后根据不同的屏幕设置字体属性和缩放倍数,如1倍屏12px,缩放为1,2倍屏缩放为0.5,3倍屏缩放为0.3333,不清楚这样做的目的是什么,貌似缩放乘以倍数是一样的效果,也就是可以用一种设置来实现,不知道理解的是不是有问题?忘大神告知。
关于淘宝h5兼容,这里有详细的介绍。使用Flexible实现手淘H5页面的终端适配
下面来看下网易的适配:
安卓1倍屏,device-width为384,html字体设置为51.2
iphone2倍屏,device-width为320,html字体设置为42
iphone3倍屏,device-width为414,html字体设置为55px
网易的缩放值始终为1,而且所有属性包括字号都是用rem来设置,不同于淘宝,网易客户端在各种终端显示内容始终是一致的,这和我们上面讲过的动态改变缩放值是一样的。选定一种宽度为标准,然后其他机型的设置即为标准机型*比例值。
至少就个人来说,我更喜欢网易的这种适配方案,这样可以保证我的页面在每个机型上都是一样的效果。
通过分析上面的几种方法,我们可以简单写一个方法,当然下面方法还没有经过大量测试,只讲方法,慎用
1 function autoSize(width){ 2 3 //如果我们设计稿为750,则传入750,否则都认为是640 4 var width=width?640; 5 6 //为了便于计算,在参照宽度下设html字号为100px, 7 8 var units=width/100; 9 var width=document.documentElement.clientWidth; 10 width=width>1080?1080:width; //设定最大值 11 width=width<=240?240:width; //设定最小值 12 var calFontSize=width/units; //计算html字体的字号 13 14 document.documentElement.style.fontSize=calFontSize+'px'; 15 } 16 autoSize(); 17 window.onresize=function(){ 18 autoSize() 19 }