移动端高清多屏适配方案

背景

移动设备发展迅猛,屏幕适配变得越来越复杂。

名词解释

提起屏幕适配总少不了以下几个概念:

  • 物理像素
  • 设备独立像素
  • 设备像素比
  • 屏幕分辨率
  • 屏幕尺寸
  • UI视觉稿

如果你不是做LCD或电子行业的话,理解起来可能比较模糊,幸好我有做手机LCD的朋友,下面我们逐个介绍。

物理像素(physical pixel)

设备像素又称物理像素,设备能控制显示的最小单位,故名思意,物理像素和设备本身硬件有关。

设备独立像素(density-independent pixel)

设备独立像素(也叫密度无关像素),可以看作屏幕中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。所以说,物理像素和设备独立像素之间存在着一定的对应关系,这就是接下来要说的设备像素比。

设备像素比(device pixel ratio )

设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到:

设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向

备注:在javascript中,可以通过window.devicePixelRatio获取到当前设备的dpr。在css中,可以通过-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)。

移动端高清多屏适配方案_第1张图片

在上图中iPhone5的设备独立像素为 320*568,设备像素比为2,那么可以计算出他的物理像素:640*1336

为什么要强调这个像素比呢?我们来看个例子。假如在屏幕上有一张图片,他的css样式如下:

width: 10px;
height: 10px;

在不同的屏幕上,css像素所呈现的大小(物理尺寸)是一致的,不同的是1个css像素所对应的物理像素个数是不一致的。
当dpr=1时, 该图片对应的设备像素为 10x10=100;
当dpr=2时,该图片对应的设备像素为 20x20=400;

结果如下:
在普通屏幕下,1个css像素 对应 1个物理像素(1:1);
在retina 屏幕下,1个css像素对应 4个物理像素(1:4);

位图像素

一个位图像素是栅格图像(如:png, jpg, gif等)最小的数据单元。每一个位图像素都包含着一些自身的显示信息(如:显示位置,颜色值,透明度等)。
理论上,1个位图像素对应于1个物理像素,图片才能得到完美清晰的展示。
在普通屏幕下是没有问题的,但是在retina屏幕下就会出现位图像素点不够,从而导致图片模糊的情况。

什么是1倍图/2倍图/3倍图?
如果1倍图对应:10X10
则2倍图对应:20X20,3倍图为30X30

你已经知道了1个位图像素对应于1个物理像素,图片才能得到完美清晰的展示。那么当一个图片的大小为10x10在dpr=2的屏幕上显示,其css为:

width: 10px;
height: 10px;

怎么做才能让它清楚的显示呢?也就是说1个位图像素对应于1个物理像素。因为此时的物理像素为20,不难猜出位图像素也应该为20,也就是采用2倍图的方案。

假如在普通屏幕下,也用了两倍图片,会怎样呢?
很明显,在普通屏幕下,10×10(css pixel)img标签,所对应的物理像素个数就是10×10个,而两倍图片的位图像素个数则是10×10*4,所以就出现一个物理像素点对应4个位图像素点,所以它的取色也只能通过一定的算法(显示结果就是一张只有原图像素总数四分之一,我们称这个过程叫做downsampling),肉眼看上去虽然图片不会模糊,但是会觉得图片缺少一些锐利度,或者是有点色差(但还是可以接受的)。

H5常见的几个问题

retina下图片高清问题

上面我们已经给出了解决办法:不同的dpr下,加载不同的尺寸的图片。可以做一个图片服务器来完成裁剪的工作。

https://img.your/path.com/xxx_200X200.png
https://img.your/path.com/xxx_400X400.png

retina下1px边框问题

设计师想要的retina下的1px边框,其实就是1物理像素宽,对于css而言,可以认为是 0.5px,这是retina下(dpr=2)下能显示的最小单位。然而并不是所有手机浏览器都能识别0.5px;,ios7以下,android等其他系统里,0.5px会被当成为0px处理,那么如何实现这0.5px呢?
最简单的做法是对元素进行缩放:

.scale{
    position: relative;
}

.scale:after{
    content:"";
    position: absolute;
    bottom:0px;
    left:0px;
    right:0px;
    border-bottom:1px solid #ddd;
    -webkit-transform:scaleY(.5);
    -webkit-transform-origin:0 0;
}

这样写起来相对比较麻烦,也可以对整个页面进行缩放:

这样的话就要求,所有的尺寸按照两倍来做,包括字体大小,元素大小等。

多屏适配布局问题

使用rem,不对页面进行缩放,因为使用缩放后,第三方插件样式修改等比较麻烦。另外需要注意一点的是,使用rem会出现页面闪烁的问题,由于初始化时需要计算页面尺寸。


doc.addEventListener('DOMContentLoaded‘', function(e) {
    
}, false);

字体大小问题

综合权衡之后还是使用rem,不使用绝对单位。

[参考文章]http://div.io/topic/1092

转载于:https://www.cnblogs.com/gaollard/p/8627668.html

你可能感兴趣的:(移动端高清多屏适配方案)