移动端网页开发必须要知道的概念

家住魔仙堡 提交于 2019-12-04 14:17:49

一、viewport

PC上的网页宽度一般最小都是1024像素,但是手机屏幕宽度没这么大,浏览器可视区域的尺寸最大也不超过手机屏幕宽度,如果直接显示PC版的网页的话,会挤作一团,排版什么的都会乱掉,怎么办呢?弄一个虚拟的网页显示视窗(viewport),这个视窗比浏览器可视区域大就可以把PC上的网页显示在手机屏幕上了(移动设备上的浏览器会把自己的viewport设为980或1024),这就是viewport中的第一个概念,layout-viewport。
layout-viewport使得PC网页可以在手机浏览器上显示,但是layout-viewport比浏览器可视区域大,因此浏览器会出现滚动条,这就产生了另一个概念,visual-viewport
visual-viewport的宽度等于浏览器的宽度,让viewport等于浏览器宽度,会自动压缩网页,这样就可以显示PC版的网页又不会出现滚动条了。
 
现在PC版网页在屏幕上能正常显示了,但是用户体验不好,因为压缩得厉害,只能不停的放大页面,看完再缩小,用户体验很太差,很多公司为了解决用户体验问题,会针对手机端开发了专用的H5版本。
但是在手机上又存在逻辑分辨率和物理分辨率不同的情况,以iphone为例,从iphone4开始,出现了所谓的高清屏,即物理分辨率与逻辑分辨率不同。
物理分辨率与逻辑分辨率的不同,会导致显示效果的不同。因此急需要一个与物理像素无关的viewport,这个viewport要解决以下问题:
 
1.不需要用户缩放和横向滚动条就能正常的查看网站的所有内容;
2.显示的文字的大小是合适,比如一段14px大小的文字,不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况是这段14px的文字无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的,不仅是字号,图片、div宽度等都是如此。
 这就是ideal-viewport,idieal-viewport与物理分辨率无无,也没有规定所有手机都使用一个尺寸,而是不同的设备拥有不同的ideal viewport。
 ideal-viewport实际上代表的就是设备的独立分辨率,假设在CSS中指定一个div的宽为375px,那么在iphone6中375px宽的div就能铺满屏幕。
 
 
我们看到很多html中都会有下面这段声明,很多前端会机械的在html中加上这段话,但不知道为什么要这么用,以及相关属性的含义,下面一起来看看。
 
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

 

width 设置layout-viewport的宽度,为一个正整数或字符串"device-width"。device-width其实就是我们前面所说的visual-viewport
initial-scale 设置页面的初始缩放值(以 ideal viewport做参考进行缩放),为一个数字,可以带小数。 缩放值越大,当前viewport的宽度就会越小,页面模糊得越来越厉害
minimum-scale 允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale 允许用户的最大缩放值,为一个数字,可以带小数
height 设置layout viewport  的高度,这个属性对我们并不重要,很少使用
user-scalable 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许
 
设置width=device-width或initial-scale=1.0其中一个就可以viewport变为 ideal viewport。width=device-width很好理解,为什么initial-scale=1.0也可以达到相同的效果呢?
init-scale=1.0是相对于ideal-viewport进行缩放的,设为1则代表让viewport=ideal-viewport。
为什么很多html写了两个属性?这是因为两者各有一个小缺陷。只设置width=device-width的话,iphone、ipad不管是竖屏还是横屏,都只认竖屏时的ideal-viewport, initial-scale=1可以解决 iphone、ipad的毛病;如果只设置inital-scale=1,在windows phone 上的IE 无论是竖屏还是横屏都把宽度设为竖屏时ideal viewport的宽度,width=device-width则解决了IE的毛病。
两个属性都可识别的浏览器,如果width跟initial-scale计算结果不一致时,viewport以哪个为准呢?
<meta name="viewport" content="width=400, initial-scale=1">

浏览器会取它们两个中较大的那个值。例如,当width=400,屏幕宽度为320时,取的是400。 

可通过document.documentElement.clientWidth获取到viewport的宽度
 
二、css中的px问题
px是一个抽象相对的像素单位,是指一个逻辑像素,在pc上1个逻辑像素就等于1个物理像素,但在移动端逻辑像素和物理像素并不相等,为什么呢?
移动端的屏幕尺寸非常小,如果1个物理像素等于1个逻辑像素的话,显示出来的文字和图片之类的清晰度不够高不够细腻,怎么办呢?把物理像素提高,即在1个逻辑像素由更多的物理像素。
那么1px到底等于多少物理像素呢?需要搞懂几个概念
 
物理像素DP(device pixels):
显示屏是由一个个物理像素点组成的,显示屏只所以能显示图像,就是通过通过控制每个物理像素点的颜色和明暗,使屏幕显示出不同的图像,屏幕从工厂出来那天起,它上面的物理像素点就固定不变。
 
独立像素DIP(Device independent Pixel ):
又叫做逻辑像素或密度无关像素,可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素)。
 
设备像素比DPR:
DPR=物理像素/逻辑像素(px) ,DPR的作用主要是确定1px等于多少个物理像素的长度。iphone6的dpr为2,那么css中的1px=2物理像素长度,也可以说成1px=4个物理像素。
window.devicePixelRatio获取
 

三、移动端图片模糊的原因

位图像素是栅格图像(如:png,jpg,gif等)最小的数据单元。每一个位图像素都包含着一些自身的显示信息。(如:显示位置,颜色值,透明度等)

理论上来说,1个位图像素对应1个物理像素,图片才能达到清晰的展示

但是在高清屏上1个位图像素会对应多个物理像素(苹果的retina高清屏使用4个物理像素来达到其他显示屏1个物理像素的效果)。由于单个位图像素已经是最小的数据单位了,它不能再被进行切割。于是为了能够显示出来,就只能就近取色,从而导致所谓的图片模糊问题。

如何解决?

很明显,由于位图像素不够分而产生模糊的情况,解决的办法十分简单,就是使用跟dpr同个倍数大小的图片。比如iphone6,一个200x300的img标签,原图就要提供400x600的大小。那么当加载到img标签中,浏览器会自动对每1px的css像素减半,可以理解为此时还是维持着1:1的css像素:物理像素,不产生模糊。这就是UI切图时为什么会给2倍图的原因。

如果普通屏幕,也就是dpr为1的屏幕,也使用了两倍的图片,会发生什么样的情况呢?

在普通屏幕下,200×300的img标签,所对应的物理像素个数就是200×300个,而两倍图片的位图像素个数则是200x300x4,于是就出现一个物理像素点对应4个位图像素点,所以它的取色也只能通过一定的算法进行缩减,显示结果就是一张只有原图像素总数四分之一,肉眼看上去虽然图片不会模糊,但是会觉得有点色差。(其实就是模糊的逆向过程)。

那能不能让img标签根据设备的dpr,自动加载相应的倍图呢?答案是可以的

img自动根据dpr加载不同的图片

 

四、高清屏下html中1px的边框比视觉图中的粗

设计师在视觉标注图上标明边框为1像素,于是你在css中很愉快的写下border:1px,结果悲剧了,在iphone6这种高清屏中看起来1px比较粗。

原因还是上面第2点的知识,1px不等于1个物理像素,在iphone6中1px等于2个物理像素,看着就会比视觉稿上的粗。

解决方案总结 

五、视觉稿如何还原? 

为了适配高清屏,UI一般会以Iphone6的物理分辨率来设计视觉稿,即视觉图的宽度为750px,为什么会选iphone6呢?因为iphone6的尺寸在手机屏幕尺寸中算是一个中间值。

还原视觉稿时,简单粗暴的做法是直接将标注的尺寸除以2来确定宽高(除以2是因为iphone6的dpr为2,750个物理像素的宽度,在iphone6上只需要375个独立像素就能铺满了),这么做在屏幕尺寸更大的手机上,两边就会留白,而在更小尺寸的屏幕上最会显示不全。

 

使用media query根据不同的屏幕分辨率来进行适配的问题:

  • 屏幕分辨率分区间:区间内无法进行区分,无法实现100%兼容,一般是用主流分辨率来进行划分;
  • 额外的工作量:响应式布局的工作都是需要开发者去实现的,带来了额外的开放量;
  • 不适合功能复杂的页面:响应式一般适合用于资讯类页面,功能复杂的网站对于页面的整体排版和样式要求较高(特别是对比PC和H5);

最好的做法是采用rem单位

rem是css3中的一个倍数单位,当为html根元素设置字体大小后,其它元素就可以根据这个字体大小,计算出自身大小。假设html的font-size为12px,一个宽度为2rem的div元素则为24px

使用rem替代px时,思路如下:

1.先假设750个像素时(根据UI出的图尺寸而定),1em代表100px(1em等于多少px,完全可以自己决定,这里只是为了方便),那么手机的独立像素为375px时,1em=100*(375/750)+'px'=50px

2.使用1rem=100px转换你的设计稿的像素,例如设计稿上某个块是100px*300px,换算成rem则为1rem*3rem

3.meta头设置(注意,inital-scale始终为1,不需要根据dpr进行换算,然后动态设置缩放比)

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

https://www.jianshu.com/p/3b45aa981e77

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!