探究移动端开发
什么使移动端开发呢?这就是在手机等移动端设备上的网页开发。 并且现在手机上的app有一部分也是h5页面,对于Android系统的手机,我们打开手机上的开发者选项,开启显示布局边界,如果发现页面有布局则是native,否则是h5页面。而当今比较流行的通过rem进行移动端的适配,所以这篇文章会主要介绍一些基本概念以及rem适配方案。
推荐文章:官方文档
第一部分:基本概念
物理像素:这个就是在屏幕上可以控制的最小显示单位,比如显示颜色的最小单位。
css像素为逻辑像素,手机上的每一个小格为物理像素。
css像素: 就是我们在设计网页时在css中使用的像素,比如:border: 1px black solid;这里的1px即为css像素,实际上这种像素就是下面我们要介绍的设备独立像素。
设备独立像素(density-independent pixel):设备独立像素又成为密度无关像素,它独立于设备,比如说是css像素,他们可以转化为物理像素。设备独立像素也称与设备无关的像素(device-independent pixel,简称DIPs),更简单的理解即为:独立于设备的用于逻辑上衡量像素的单位。
设备像素比:即物理像素/设备独立像素=设备像素比(device pixel ratio),设备像素比的英文即dpr,我们在JavaScript中可以通过window.devicePixelRatio获取到当前设备的dpr。那么设备像素比是怎么一回事呢?此问题的关键要归结为:css中的1px并不等于设备中的1px。也就是说:物理像素和设备独立像素是不一样的。在早先的移动设备中,比如iPhone3,它的分辨率是320X480(此分辨率很低),一个css像素(设备独立像素)确实等于一个屏幕物理像素,此时dpr为1,但是随着科技的发展,移动设备的像素密度(下面会介绍)越来越高,从iPhone4开始,苹果公司便推出了Retina屏,在屏幕尺寸没有变化的情况下分辨率却大大提高了,成了640X960,这意味着:同样大小的屏幕上,物理像素多了一倍,而css像素没有变,于是一个css像素是等于两个物理像素的,此时dpr为2。现在标准的PPI已经很少见了,大多是Retina视网膜设备,比如,iPhone5s的设备像素比为2,iPhone6s的设备像素比为3。(注:Retina视网膜屏幕即PPI值超过300的超高密度屏幕,只是苹果公司给它起了一个高大上的名字而已)。大家可以在 http://DevicePixelRatio.com这个网站中可以看到更多设备的dpr。下图即说明了物理像素和css像素之间的关系:
像素密度(PPI):即pixel per inch,由英文可知,PPI即为每英寸所具有的像素点(物理像素),PPI的值越高,那么在单位英寸中参与显示画面的像素越多,于是画质越好,实际上PPI就是像素密度(pixel density)。那么PPI是什么计算出来的呢?看下面的公式:
比如,iPhone6 Plus的像素分辨率为1920X1080,屏幕尺寸为5.5英寸(对角线),就可以得到PPI约等于401.
pt:pt是什么呢?它和px的区别又在哪里呢?实际上px是pixel,即像素;而pt是point,是印刷行业的常用单位,等于1/72英寸。主要区别在于:px是一个点,它不是自然界的长度单位,这个点可以画的很大,也可以画的很小,如果点很小,那么就说明分辨率高,否则分辨度低,它是一个相对的长度单位。而pt是专用的印刷单位”磅“,大小为1/72英寸,总之就是说它是一个自然界中的标准的长度单位,也成为”绝对长度“。
第二部分:移动端的适配方案
那么,什么是适配呢? 在做pc端的时候,只要按照设计图的尺寸进行设计就好,但是在做移动端页面的时候,设计师黑了,一份宽度为640px的设计图,这时候把这份设计图实现在各个手机上的过程就是适配。
如今比较流行的便是利用rem布局。即依照某特定宽度设置rem值页面中任何需要弹性适配的元素,尺寸均换算为rem进行布局。重点:当页面渲染时,根据页面的有效宽度进行计算,以调整rem的大小,这时页面中利用rem设置大小的元素就可以同时缩放了(动态性),以此达到适配的效果。
那么什么是rem呢?rem值即在样式中设置的html{font-size:20px;},其中的20px即为rem值,rem的全称为font size of root element,即根元素html的字体大小。简单的来说,它是一个相对单位,说起rem,大家一定会想起em单位,em(font size fo the element)是值相对于父元素的字体大小的单位。em和rem之间很相似,只是在计算的规则来说一个相对于根元素一个相对于父元素。并且在em的过程中,由于复杂的嵌套关系,很容易导致混乱,所以使用rem是一个不错的选择。
比如当设计师给了我们一份640px的设计稿时:
我们设置了rem为1px,这样,在id为square的div中设置宽度为20rem即为20px,高度同样是20px,但是如果需要应用的不是640px宽度的屏幕,而是1280px宽度的屏幕,这时只要font-size修改为2px,那么高度宽度就会成为40px了。又比如下面这张图片:
如果我们拿到的640px的设计稿(蓝色背景),当运用于640px的页面上时,屏幕对比比例为1,这时设置rem为20px,对于页面中的一个元素,设置宽度为10rem,那么元素宽度实际上就是20X10px即200px,但是,如果这个页面的使用屏幕不是640呢,而是放在更小的如384px的屏幕上呢?这时,如果不做任何改变,那么页面一定是不能完整的显示的,这时,因为380/640=0.6,即屏幕的宽度为原来的0.6倍(一般不需要考虑高度),那么只需要将rem修改为20X0.6=12px,这时元素的宽度10rem即10X12px就成了120px了。但是,由于我们得到的设计稿是使用px进行设计的,所以,如果我们要使用rem布局,就需要每次使用这个px值除以rem得到rem的倍数,很有可能还是个小数,所以这样是非常麻烦的,但是我们可以通过cssrem插件(点击即可安装)来解决这个问题,即当我们输入px单位时,该插件会自动转化为相应的rem值。
这个问题解决了,可是,怎么才能通过JavaScript动态地修改rem?
淘宝团队的flexible.js是一个很好的解决方法.那什么是flexible.js呢?
- 手机淘宝2014年开始推行的flexible设计,它是responsive的低端形态和基础。
- 手机淘宝使用JS动态的写meta标签,手机淘宝的flexible方案是综合运用rem和px两种单位+js设置scale和html字体。
使用方法:
一.我们可以将它在gitbub上下载下来,然后再<head>标签中引用这个js文件,如下所示:
二.另外一种将该文件添加到html中的方法是直接加载阿里CDN的文件,方法如下:
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
无论使用哪一种方法,值得注意的是:
1.为了适配的更快,并且因为我们需要使用这个js文件动态的修改meta元素内容,如果最后加载,那么页面将会发现一个“突变”,影响用户体验,因此这个文件一定要在head中就引用,而不能在</body>之前引用。
2.在使用lib-flexible时,通常不需要写:<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>因为在这个js文件中都已经自动地设置了,它会自动处理:在执行这个js之后,会在<html>元素上增加一个data-dpr属性以及一个font-size的值,比如30px;这样一来,页面中的所有元素,都可以通过rem单位来设置,他们会根据html元素的font-size值做出相应的计算,从而实现屏幕的适配效果。在flexible中因为在Flexible中,只对iOS设备进行dpr
的判断,对于Android系列,始终认为其dpr
为1
。
那么说了这么多flexible的实质是什么呢?实际上,flexible实际上就是通过JS来动态改写meta标签。如下:
- 动态改写<meta>标签。
- 给<html>元素添加data-dpr属性,并且动态改写data-dpr的值。
- 给<html>元素添加font-size属性,并且动态改写font-size的值。
但是,编写css时,除了font-size之外,其他元素都要按照设计稿的尺寸转化为rem单位的值。显然,我们在iPone3G和iPhone4的Retina屏下面看到的文本号是相同的,也就是说,我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏幕手机上看到更多文本,而且现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px和24px,所以我们不希望出现13px和15px这样的奇葩尺寸。这样,rem并不适合用到段落文本上,所以在flexible整个适配方案中,考虑文本还是使用px作为单位,只不过要用到[data-dpr]属性来区分不同dpr下的文本字号的大小。
即dpr为1(物理像素/设备独立像素=1)时字体大小为12px,在dpr为2(物理像素/设备独立像素=2)时,如果还是用12px的字体大小,那么该字体明显会很小,所以需要设置为24px,对于dpr为3时同理。
注意:[data-dpr="2"] div
在[data-dpr]和div之间一定要有空格,否则没法实现功能。
第三部分:常用API
[Number] lib.flexible.dpr
当前页面的dpr值
[Number] lib.flexible.rem
当前页面的rem基准值
[Number|String] lib.flexible.rem2px([Number|String digital])
把rem转换为px
[Number|String] lib.flexible.px2rem([Number|String digital])
把px转换为rem
lib.flexible.refreshRem()
刷新当前页面的rem基准值
第四部分:实例
下面这篇文章讲的很好,大家可以作为参考。
微网站—使用flexible.js实现移动端设备适配
官方文档:https://github.com/amfe/lib-flexible
更多相关文章:
http://isux.tencent.com/web-app-rem.html
http://www.cnblogs.com/2050/p/3877280.html
http://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html (推荐)
http://eux.eeyes.net/blog/article/582ecb1522c84bda4a814a88(推荐)(查看flexible.js的源码)
http://www.jb51.net/css/29331.html
http://caibaojian.com/mobile-responsive-example.html
http://caibaojian.com/mobile-knowledge.html (移动前端知识总结)