New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
zhaoqize opened this Issue Jan 10, 2018 · 0 comments

Comments

Projects
None yet
1 participant
@zhaoqize
Owner

zhaoqize commented Jan 10, 2018

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像素,在这两个机型上的表现是一致的)

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

  • 小米5的设备的独立像素为 640pt x 360pt ,而其dpr为 3 ,所以我们知道其物理像素为1920px x 1080px
  • 红米note的设备的独立像素为 640pt x 360pt ,但是其dpr为 2 ,所以我们知道其物理像素为1280px x 720px

在不同的屏幕上,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
延伸:

  • 在dpr=1的iphone3中呢?
  • 在dpr=2的iphone6中呢?

获取参数:
iphone3

  • dpr : 1
  • dp : 320 x 480
  • px : 320 x 480

iphone6

  • dpr :2
  • dp :375 x 667
  • px : 750 x 1334
    同样:
1.在html中设置一个font-size是 (320/10) 32px 的情况下,div宽度设置 10rem ,能够在 dpr=1 的手机中显示 320px 的宽度
2.在html中设置一个font-size是 (375/10) 37.5px 的情况下,div宽度设置 10rem ,能够在 dpr=2 的手机中显示 360px 的宽度

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

参考:

@zhaoqize zhaoqize changed the title from 终极理解移动开发的页面适配 to 对手淘移动开发适配的实例思考 Jan 11, 2018

@zhaoqize zhaoqize added the Blog label Jan 11, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment