做有态度的前端团队

网易FEG前端团队

屏幕尺寸、分辨率、倍率到底是什么鬼

目前我们做移动端项目几乎不需要考虑为什么要这样写样式,为什么设计稿上100px我们直接写成1rem,移动端的屏幕尺寸那么多变,为什么能轻松兼容?那我们得从移动端的屏幕尺寸来探索一下其中的原理,首先就得了解这些费解的概念。
我在网上收集了很多资料,众说纷芸,我按自己的理解整理了这篇文章,如果有理解不当的地方,请指正。

屏幕尺寸

即我们通常说的尺寸是多少多少英寸啦,指的是屏幕对角线的长度。比如iphone6的屏幕尺寸是4.7英寸
1.png

设备像素DP(device-pixels)

很多地方又叫设备屏幕尺寸、设备物理像素、屏幕分辨率等等,我感觉是一个概念。比如iphone6是1334*750

像素密度PPI(pixels per inch)

每英寸屏幕上的像素个数,不同屏幕不一样,PPI越大屏幕显示得越清晰,比如iPhone 3gs的设备像素是320×480,iPhone 4s的设备像素是640×960。刚好两倍,然而两款手机都是3.5英寸的,前者的像素密度是后者的两倍,显示出来的画面更清晰细腻。从网上扒了个图:
2.png

设备独立像素dips(device-independent pixels)

有的地方也叫逻辑像素。其实也就是我们开发中的document.documentElement.clientWidth。只要逻辑像素相同,显示区域的内容就相同。

倍率DPR(devicePixelRatio)

有的地方也叫设备像素比,是设备像素dp和设备独立像素dips的比例,
也就是dpr = dp / dips

倍率与逻辑像素

概念介绍完了,我们来研究一下这两者的关系,下面这个例子是在网上看到的,感觉解释得比较清晰。
我们以iphone3gs(倍率为1)和iphone4s(倍率为2)来举例,这两者屏幕尺寸都是3.5英寸,大小是一样的,但是分辨率相差了一倍。那么如果按PC网页来考虑,iphone3gs的屏幕分辨率为320480,iphone4s的则为640960,那么在iphone4s上显示的内容应该比在iphone3gs上显示的多,如下图:
3.png

可是实际上它们显示的内容是一样多的,这是为什么呢?这是因为Retina屏幕把2×2个像素当1个像素使用。比如原本44像素高的顶部导航栏,在Retina屏上用了88个像素的高度来显示。导致界面元素都变成2倍大小,反而和3gs效果一样了。画质却更清晰。

4.png

我们的设计稿是以iphone6为基准来做的,而iphone6的屏幕像素宽是750px,逻辑像素是375px,那么为什么我们的设计稿是750px宽的呢?就是因为切图时获取到的图片是页面上的两倍大,在retina屏幕上实际上是相当于把图片缩小了一倍的,这样可以看到更清晰的图片。如果我们用375px的图片,那么retina屏幕还有什么意义,显示出来的效果就跟倍率为1的屏幕一样了,没有那么细腻了。

我们现在的屏幕适配方式

我们的_reset.less文件里面有一段媒体查询代码

html{ font-size: 312.5%; } 
@media screen and (max-width:359px) and (orientation:portrait) {
 html { font-size: 266.67%; } 
}
@media screen and (min-width:360px) and (max-width:374px) and (orientation:portrait) {
 html { font-size: 300%; } 
}
@media screen and (min-width:384px) and (max-width:399px) and (orientation:portrait) {
 html { font-size: 320%; } 
}
@media screen and (min-width:400px) and (max-width:413px) and (orientation:portrait) {
 html { font-size: 333.33%; } 
}
@media screen and (min-width:414px) and (max-width:431px) and (orientation:portrait){
 html { font-size: 345%; }
}
@media screen and (min-width:432px) and (max-width:479px) and (orientation:portrait){
 html { font-size:360%; }
}
@media screen and (min-width:480px)and (max-width:639px) and (orientation:portrait){
html{ font-size:400%;}
} 
@media screen and (min-width:640px) and (orientation:portrait){
html{ font-size:533.33%;}
}

后面的那些百分比值是怎么来的呢?

312.5%这个基本值是为了计算方便
页面的字体默认是16px,我们把根节点字体设置为312.5%,那么就是16*312.5%=50px,对应设计稿上的100px,那么设计稿上100px的元素,我们样式表里面写成1rem就可以了。

在不同屏幕尺寸(指的是逻辑像素)下面,我们把根节点的字体按比例调整一下,那么页面就按比例进行了缩放,那么我们在不同尺寸的屏幕上看到的页面效果就是相同的了,这个比例是怎么计算的呢,我们拿
@media screen and (min-width:360px) and (max-width:374px) and (orientation:portrait) {
html { font-size: 300%; }
}
这个范围来说,(375/360)*312.5%=300%,于是就得到了这个比例。
> PS:其实这个媒体查询并不是最终起作用的,它的存在只是为了防止js没加载到的时候就先渲染了页面,等后面js加载完后,页面样式改变太大而发生页面跳动,体验不好。最终起作用的是下面这段js代码:
可以回头读一下(点这里—>)移动端开发规范感受一下

$("html").css("font-size",document.documentElement.clientHeight/document.documentElement.clientWidth<1.5 ? (document.documentElement.clientHeight/603*312.5+"%") : (document.documentElement.clientWidth/375*312.5+"%"));
 //单屏全屏布局时使用,短屏下自动缩放
//$("html").css("font-size",document.documentElement.clientWidth/375*312.5+"%");//长页面时使用,不缩放

手机阅读请扫描下方二维码:

已有 4 条评论

  1. floyd

    科普文写得挺好~~~解释了平常经常听到但却不知道啥意思的概念~~ ali-61.gif ali-61.gif ali-61.gif

    1. gzxiejianan

      有没有打赏功能 顺便 你的表情不够多啊

      1. 瑶一瑶

        你可以直接发微信红包给我 ali-59.gif

  2. wangzixuan01

    ali-61.gif

添加新评论

ali-40.gifali-41.gifali-42.gifali-43.gifali-44.gifali-45.gifali-46.gifali-47.gifali-48.gifali-49.gifali-50.gifali-51.gifali-52.gifali-53.gifali-54.gifali-55.gifali-56.gifali-57.gifali-58.gifali-59.gifali-60.gifali-61.gif