移动端开发中,有一些基本概念需要理解清楚,才能更好的组织编程逻辑。在刚接触时,移动端视口的缩放和rem单位的缩放搞混淆了,弄得自己很蒙圈。所以仔细总结下自己的理解。
移动端的适配,我理解为两点:
第一点就是视口的缩放配置,牵扯出视口和像素等概念。目的是为让我们的CSS样式中逻辑像素匹配到手机终端的物理像素,让网页视图适合手机屏幕。虽然在代码中只是一个语句就解决的问题,但要理解它,要弄懂很多概念。《关于像素Pixel历史的详解看下一篇文档》
第二点就是rem单位的使用,目的是为了我们只需要一份代码就可以适应大部分不同屏幕的手机。
以上两点虽然实现的目的不同,但采用的方法原理基本一样,都用到缩放因子来解决问题。第一种是DPR,第二种是rem。
自适应:指在同一终端下,页面布局能根据视口本身变化而自动调节布局,比如PC端浏览器页面尺寸的变化,resize事件;
响应式:指页面能在根据检测到的不同终端类型,自动调整布局。比如手机、平板、电脑等不同终端下的响应。媒体查询@media的语法,要熟悉。
一、视口
视口,从字面上用常规思维可以理解为人眼的可视区域。在移动端开发中,常将视口抽象划分为布局视口、视觉视口和理想视口。为什么这么划分呢?我觉得还是为了让我们更好理解CSS像素和设备像素的区别,也就是逻辑像素和物理像素的区别。
在PC端开发书写CSS时,对元素的尺寸的限定单位经常就是PX,即像素大小。从一开始接触和学习过程中,一直都是使用PX,导致我们的思维产生定式,总觉得CSS中元素的大小的度量就只有PX了。
另一个默认的思维定式就是在我们CSS代码中,CSS的PX像素单位就是真实的代表一个像素,导致当网页开发转到移动端开发时,一个新概念的出现对我们冲击特别大,很难转过弯来理解,比如现在要说的视口的理解,牵扯出来的CSS像素和设备像素的概念。
其时,只要记住一点,CSS像素PX只是代表WEB网页中的一个度量单位,可以理解为同rem和em等单位一样,需要有一个参照尺寸才能确定其实际大小。比如rem参照根字节点的字体大小来确定自身大小,em参照父级元素字体大小来确定自身大小。思维定式中rem和em参照物是我们“绝对单位”像素PX而定的。
像素PX大小其时是相对显示硬件中的发光点(Dot)定义的,一个发光点常称为一个物理像素。
关于像素Pixel的前世经生,可以看这里:https://blog.csdn.net/zssureqh/article/details/78768942
显示硬件中的发光点(Dot)与图像分辨率中的像素(Pixel)是容易混淆的两个概念, 显示硬件中的点可以说是硬件设备最小的显示单元,而像素则既可是一个点,又可是多个点的集合。
在扫描仪扫描图像时,扫描仪的每一个样点都是和所形成图像的每一个像素相对应的,此时扫描时设定的DPI值(Dots Per Inch)与扫描形成图像的PPI(Pixel Per Inch)值是相等的,此时两者可以划等号。但在许多情况下,两者的区别是相当大的。比如,分辨率为1 PPI的图像,在300DPI的打印机上输出,此时图像的每一个像素,在打印时都对应了300×300点。在计算机显示器的运用上也存在类似问题,比如 12英寸显示器的有效显示区域约200mm×160mm,如果荧光屏的光点直径为0.31mm,通过换算可知荧光屏上最大可显示的光点数为640(200 ÷0.31)×480(160÷0.31),相应的分辨率为80DPI。这个80DPI是这样来的:640Dot÷(200mm÷ 25.3995mm/Inch)≈80Dot/Inch或者 480Dot÷(160mm÷25.3995mm/Inch)≈80Dot/Inch 。
在这种情况下,显示卡的显示模式最高可设置为640×480,这时1 Pixel由1 Dot组成。如把显示卡的显示模式调整为320×200,在显示一幅320×200的图像时,一个像素就要对应于四个光点。
上面就解释了我们在PC端书写CSS样式时直接使用PX,不考虑适配的原因,因为电脑出厂设置默认都是PPI = 显示屏DPI的,1:1关系,即dpr(devicePixelRatio,设备像素比 = 物理像素(即发光点)/逻辑像素(px)),这是显示器的“最佳分辨率,也是我们PX像素比例所依赖的分辨率。
有两种现象:
1、我们将电脑屏幕的分辨率调低,就会出现一部分黑边,即有显示硬件中会有部分不被点亮的发光点。实现发光的点还是按设置的分辨率,即像素与点一一对应。所以在PC端,DPR都是1.
2、我们在电脑端上对一张图片进行放大和缩小,难道说我们就改变了图片的像素尺寸了嘛?实际不是,图片长宽方向的像素尺寸至少数值上没有改变的。电脑改变的只是每个图片每个像素对应的发光点数量布局。跟上面扫描仪扫描图片一个道理。图片放大4(2*2)倍,图片原来一个像素对应一个发光点变为现在一个像素对应2个发光点。所以说像素是可以被拉伸的。
所以后面提到的手机端适配也是通过对像素拉伸达到的,就是说让一个逻辑像素对应更多的发光点(物理像素)。
手机屏幕在最开始的时候,像素与发光点也是一对一的,此时在手机布局页面操作就跟电脑PC端一样,直接用像素PX度量就好了。但时代是进步的,科技更是在飞速的发展,屏幕的分辩率越来越高,即同样大小的屏幕所能产生的光点越来越多,屏幕的对应的像素也越来越多。特别是从苹果公司在IPONE4中采用Retina视网膜屏之后。虽然像素密度的提升,页面颜色的显示量多为细致。但却给移动端页面布局带来了困扰。
方便大家理解,数据和单位权当假设,在最初的时候一个平方厘米的面积上就显示10*10=100个像素点,那我CSS中某个字体大小就设为10PX(字体大小以宽度像素为准),我们在屏幕上看到这个字体感觉很好,但现在技术更新了,同样1个平方厘米的面积上,我可以显示100*100=10000个像素点,那如果DPR还保持一比一的关系,那字体还是被显示为10px(10个发光点),那此时我们看到的字体是不是变得小了很多,相当于原来字体的宽度和长度同比例缩小10倍。
比如ipone3和ipone4,同样是对角线8.9厘米大小的手机屏幕,ipone3能显示的像素是320*480,而ipone4能显示的像素是640*960。像素密度多了2倍。相当在ipone3上显示100px的字,在ipone4上同样设置100px,但看上去字体大小会比ipone3缩小了2倍。
看下这张图,手机屏幕的像素越来越高,那是不是在手机上显示的字体越来越小呢?
如果CSS里字体尺寸的像素标准还维持原来PC端的DPR=1标准不变,那势必会导致这样的结果。所以苹果公司率先在手机端改变了DPR的比值。因为包括IPONE3之前几代手机里,手机的物理像素(即设备显示屏的发光点)和CSS世界里的逻辑像素单位是1:1的关系,字体大小在手机里感官体验也是很好的。所以既然像素PPI增加了2倍,那这个比例关系就改为2:1啦。就是说,手机屏幕的2个物理像素相当于CCS里的1个逻辑像素。这样屏幕尺寸没变都是3.5寸屏,像素密度增加了两倍,但因像素单位也增加2倍,所以也保证了字体大小没变化。这里我们常说的DPR。它是由手机厂商根据自己手机屏幕尺寸和像素PPI考虑的,在手机出厂时就设定好了。
像上面字体大小设定一样,厂商根据手机屏幕尺寸大小,会有一个最符合这个屏幕尺寸页面设计方案,使得整个页面刚好全部覆盖手机屏幕,屏幕不会产生滚动条,用户视觉感官最佳的页面大小。这个视口就是我们称为理想视口,此时视口的宽度就定义为设备宽度device-width,这个device-width就不是屏幕分辨率所指的像素宽度了,是一个中间层。
所以这里我们就可以定义视口了:
把刚好符合手机屏幕尺寸显示完美页面的区域称为理想视口ideal layout;
根据放大DPR倍方便我们使用物理像素进行页面布局的页面称为布局视口layout viewport。
当代码中没有限制缩小或放大设置时,用户可以对浏览页面进行缩小或放大,此时缩放后用户看见页面内容区域就叫视觉视口visual viewport 。
如果每个元素的大小都要这样逐个根据设计稿进行换算,那效率肯定不行。那如果反过来想,我把页面中CSS的像素单位全部都放大DPR倍的比例,就是用布局视图来写,就刚好对应设计稿的单位大小啦,整个页面写完后再整体将页面的比例缩小1/DPR倍,就刚好回到CCS对应的逻辑像素单位啦。
所以移动端html文档中JS代码经常有下面的语句:
<meta id="viewport" name="viewport" content="width=device-width; initial-scale=1/DPR; minimum-scale=1/DPR; maximum-scale=1/DRP; user-scalable=no;">
语句分析:
content="width=device-width:指定手机浏览器显示的页面宽度刚好符合理想视口的宽度。Device-width:设备屏幕宽度,就是理想视口宽度。由手机厂商根据手机分辨率和自定义DPR算出,在手机出厂里就设置好的。
initial-scale=1/DPR:由于我们在页面代码中书写的像素值都是布局视图中手机的物理像素值大小,所以需要对页面进行初始化缩小1/DPR倍。
minimum-scale=1/DPR; maximum-scale=1/DRP; user-scalable=no;" 是指定理想视口下页面能被最大的缩放、最小的缩放、以及是否允许用户缩放进行设置。前两项是允许用户操作视觉视口的最大和最小缩放。
最后以这张图总结:
iphone手机型号 | 屏幕尺寸 | 像素尺寸 | 屏幕像素密度PPI | 理想视口尺寸 | 缩放DPR |
ipone2G/3G/3GS | 3.5 | 320 480 | 163 | 320 480 | 1 |
ipone4/4s | 3.5 | 640 960 | 326 | 320 480 | 2 |
ipone5/5S/5C/SE | 4 | 640 1136 | 326 | 320 568 | 2 |
ipone6/6S/7/8 | 4.7 | 750 1334 | 326 | 375 667 | 2 |
ipone6plus/6S+/7+/8+ | 5.5 | 1242*2208 | 401 | 414*736 | 3 |
iponeX | 5.8 | 1125*2346 | 458 | 375*812 | 3 |
- G指网络信息Generation S就是speed plus +大屏
- 1 inch = 2.54cm = 25.4mm
- 像素(Pixel):Picture Element(图形元素)的简称。在计算机中每块像素都具有固定地址,通过地址为其分配颜色。所以也可以理解为屏幕上每个分配颜色的最小色块。
- 屏幕尺寸:指的是显示屏对角线的长度(diagonal)。我们通常所说的iPhone5屏幕尺寸为4英寸、iPhone6屏幕尺寸为4.7英寸。
- 屏幕分辨率:指屏幕上以水平和垂直方向显示的像素个数
- 像素密度PPI:PPI(Pixel Per Inch by diagonal):表示沿着对角线,每英寸所拥有的像素(Pixel)数目
- DPI,物理像素与逻辑像素的比例
- DPI中的点(Dot)与图像分辨率中的像素(Pixel)是容易混淆的两个概念, DPI中的点可以说是硬件设备最小的显示单元
- 在IPONE4上苹果公司使用了Retina屏技术,并非苹果原创,是摩托罗拉创造的,但是苹果公司首次应用在手机上,其它手机厂商陆续也采用该技术,使得该技术得到普遍应用。
- 理论上,只要技术不断发展,单位面积能增加像素数量会越来越多,但是人的肉眼分辨率是固定的,只要能满足让人眼感受不到像素的颗粒度就可以啦,一味提高PPI,人的视觉感官到权限后也不会再有更好的感受,就无畏增加成本了。所以根据屏幕尺寸,到底设置多大的PPI,苹果有自己的Retina计算公式。所以你看后面几代苹果手机都差不多保持在相同的PPI上。
- 布局视口的宽度在手机上,可以通过document.documentElement.clientWidth来获取。
- 在设置了<meta />标签以后,device-width值可以用window.innerWidth来获取device-width值