zhaoqize / blog

✍️qize的博客:原创文章、外文翻译、技术总结和演示代码
https://zhaoqize.github.io/blog/
MIT License
280 stars 74 forks source link

对手淘移动开发适配的实例思考 #11

Open zhaoqize opened 6 years ago

zhaoqize commented 6 years ago

rem

从机型的实例来理解

机型: 小米5

  • 物理像素(px): 1920 x 1080
  • 独立像素(pt): 640 x 360
  • dpr: 3
  • 宽高比:16 : 9

    机型: 红米note1s

  • 物理像素(px): 1280 x 720
  • 独立像素(pt): 640 x 360
  • dpr: 2
  • 宽高比: 16 : 9

问题:实现div的宽度在不同机型上面的兼容 代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>h5</title>
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0" name="viewport">
    <style>
        html,body {
         margin: 0;
         padding: 0;
        }
    </style>
</head>
<body>

<div style="width:200px; height: 30px; border: 1px solid red">
    zqz测试数据
</div>

</body>
<script type="text/javascript">
    alert('dpr:' + window.devicePixelRatio);
</script>
</html>                                                                              

我们想要div的宽度与屏幕的宽度相同,我们如果将div的宽度写死肯定有问题,我们先写个width=720px,效果如下:

很明显,两个手机全部都是右边超出了,你很定很好奇,物理像素不是720么?至少红米手机应该显示正确把?

这里就牵扯到 物理像素(px)和 设备像素(dp/pt) 和 dpr 等概念。

物理像素(physical pixel) 物理像素又被称为设备像素,他是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。正是这些设备像素的微小距离欺骗了我们肉眼看到的图像效果。

设备独立像素(density-independent pixel) 设备独立像素也称为密度无关像素,可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素),然后由相关系统转换为物理像素。

CSS像素 CSS像素是一个抽像的单位,主要使用在浏览器上,用来精确度量Web页面上的内容。一般情况之下,CSS像素称为与设备无关的像素(device-independent pixel),简称DIPs。

屏幕密度 屏幕密度是指一个设备表面上存在的像素数量,它通常以每英寸有多少像素来计算(PPI)。

设备像素比(device pixel ratio) 设备像素比简称为dpr,其定义了物理像素和设备独立像素的对应关系。它的值可以按下面的公式计算得到:

设备像素比 = 物理像素(px) / 设备独立像素(DP/PT)

更多手机信息见Device Metrics

如果想要宽度正常的话,我们只需要将宽度改成width=360px即可。因为这样的话

1个物理像素 = 1个设备独立像素

然而这么改肯定不现实,种类繁多

(其实这个里还有个问题,因为这两个手机的设备独立像素是一样的,所以无论写多少css像素,在这两个机型上的表现是一致的)

当然这也是因为在有限的可见区域内,提高了像素密度,显示就更清晰

在不同的屏幕上,CSS像素所呈现的物理尺寸是一致的,而不同的是CSS像素所对应的物理像素具数是不一致的。在普通屏幕下 1 个CSS像素对应 1 个物理像素,而在dpr为2的屏幕下, 1 个CSS像素对应的却是 4 个物理像素。

我们希望的是我们写一个固定数值,而计算出不同的px。

rem的出现,让我们这个想法得以实现。

针对上面红米和小米5的例子,我们可以这么设想:

1.在html中设置一个font-size是多少的情况下,div宽度设置多少rem,能够在 dpr=2 的手机中显示 360px 的宽度?
2.在html中设置一个font-size是多少的情况下,div宽度设置多少rem,能够在 dpr=3 的手机中显示 360px 的宽度?

手淘的适配方案的核心代码:

var dpr = window.devicePixelRatio;
var width = document.documentElement.getBoundingClientRect().width;
if (width / dpr > 540) {
    width = 540 * dpr;
}
var rem = width / 10;

为什么是 540? 见540怎么得来的

这样的话,对于上面的2个自问,已经得出了答案:

1.在html中设置一个font-size是 (360/10)36px 的情况下,div宽度设置 10rem ,能够在 dpr=2 的手机中显示 360px 的宽度
2.在html中设置一个font-size是 (360/10)36px 的情况下,div宽度设置 10rem ,能够在 dpr=3 的手机中显示 360px 的宽度

image 延伸:

获取参数: iphone3

iphone6

所以,目的达到,无论我们的设备宽度是多少,只要按照这个规律,我们只需要设置10rem,必定会是屏幕的宽度。

参考:

👆返回主页查看更多文章👆