移动端dpr值

1
window.devicePixelRatio // iphone6为2 iphone6s为3

1
2
3
screen.width/height // 屏幕的宽高值
window.innerWidth/innerHeight // 浏览器尺寸内的CSS像素,即窗口文档显示区的宽度/高度(CSS像素会缩放,所以同一个浏览器宽度下这个取值是可能不同的)
window.outerWidth/outerHeight // 窗口文档显示区加上工具条与滚动条窗口的宽度与高度

视口(viewport)
我们进行网页布局的时候设置html元素宽度为100%,这个100%是依据什么设置的呢?浏览器窗口用CSS像素衡量的宽度(window.innerWidth)还是别的呢?我们可以发现在PC端的浏览器上设置100%,html元素的px宽度就等于浏览器宽度;而在移动端不管是在什么设备上,html设置100%,基本上宽度都等于980px。

布局视口
宽度设置是根据布局视口来算的,只是PC端布局视口就等于浏览器宽度,而移动终端由于屏幕宽度较窄,为了显示在PC端网页显示的网页能在移动端基本能看,所以浏览器厂商一般将其设为980px然后进行缩放,让网页在窄屏幕上能够全部显示。布局视口尺寸可以通过

1
document.documentElement.clientWidth/Height

获取。虽然document.documentElement就是html元素,但是取值却不是取的html元素的宽度。

同时我们做的媒体查询中判断的max-width也是判断布局视口的宽度。

1
2
3
4
5
@media all and (max-width: 400px) {
.box{
width: 300px;
}
}

视觉视口
视觉视口就是用户能够看到的窗口,单纯的用视觉去描述它就是浏览器屏幕的大小。
用CSS像素去描述就是:视觉视口的大小就是屏幕大小范围内CSS像素堆积的总面积,不管CSS像素是否缩放。

移动端布局需要达到的效果
我们希望一个网页放到移动端的浏览器中不会影响视觉效果,然后又利于开发。所以最好的方法就是设置布局视口的宽度正好等于屏幕的大小(这里的大小是指视觉上的而不是CSS像素单位上的,意思就是比如375的屏幕宽度下,将布局视口设置为屏幕宽度,也就是device-width,CSS像素横向有375个单位,设置375px即可满屏;如果将布局视口设置为设备宽度的两倍即750px,面积增大4倍,同时设置initial-scale为0.5,面积又缩小四分之一正好又是屏幕的大小。),这样的效果就是设置100%的时候保证就是屏幕宽度。(说的比较啰嗦)

1
2
3
4
5
6
7
8
<!--设置布局视口等于device-width-->
<meta name="viewport" content="width=device-width">
<!-- 只设置缩放值也能将布局视口宽度设置为屏幕宽度,设置为0.5时由于CSS像素缩放了0.5,填到屏幕中的CSS像素数量正好是屏幕宽度 -->
<meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<!-- 这是兼容写法 -->
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1,user-scalable=no">

移动适配方案
第一种方案

第一种方案是直接设置width=device-width,这样能够保证宽度一致,但考虑到苹果的Retina屏幕设计师出设计稿的时候都是放大了一倍设计稿,比如640px(基于iphone5)、750px(基于iphone6)。如果我们拿到的设计稿是750px宽,在设置缩放比为100%、布局视口等于屏幕宽度的情况下,我们拿到的设计稿宽度是大了一倍的,(网页中设置375px沾满屏幕,而设计稿切出的图是750px),所以在转换成网页的时候设置宽度需要将设计图的宽度除以2来,如果考虑到iphone6 plus的dpr为3,要保证在6 plus下图片还是高清,就需要将750px的设计稿再放大1.5倍,用@3倍图切出来。以上可以知道这种方案不需要动态的去根据屏幕dpr不同来设置meta标签内容,直接一句话搞定,然后需要调整的地方通过媒体查询来做。

第二种方案

第二种方案是固定设置布局视口的宽度,比如设置为640,或750,原理待研究。

第三种方案

第三种方案就是淘宝的flexible了。这个解决方案只解决苹果设备上的dpr为2和3的情况,不考虑安卓设备也不考虑pad。做的事情也很简单,就是动态设置meta标签的内容,和第一种方案不同的是没有设置为width=device-width,而是通过设置initial-scale来缩放布局视口,dpr为1,缩放为1;dpr为2,缩放0.5;dpr为3,缩放0.3333;通过这种方法使得布局视口在视觉上还是屏幕大小但CSS像素数量却增加了4倍/9倍。而这样的直接好处就是比如iphone6的视觉视口横向有了750个CSS像素点,和设计图保持一致了,同时CSS像素缩放0.5解决了经典的1px像素问题

该方案的核心原理是通过window.navigator.appVersion判断是否是iphone,其他的比如ipad、Android直接设置dpr为1,然后通过 1/ dpr 得到缩放值。

H5移动多终端适配全解 - 从原理到方案