引子
混沌诞生之初,标题里的六个概念是都没有的。我们就从最初代iPhone 1说起。
iPhone 1的分辨率是320x480像素,除此之外没有任何其他的参数可言,也没有标题中提到的5个概念。因为这种设计在当时看起来很完美。这种设计理念一直维持到iPhone 3都没有变。
从iPhone 4开始,苹果提出了新理念:视网膜屏,也就是:我们的屏幕分辨率不再是320x480,而是翻了一倍,成了640x960像素。当时有很多人觉得茫然,因为在电脑显示器上的一贯理念被苹果推翻了。“差不多大的手机,怎么可能像素翻一倍呢?”
苹果会告诉你,我把像素拿刀切的更小了,原来的一个像素我现在拿刀切成了4个像素,所以同样的手机大小,像素更多了,因为像素密度更大了,单个像素更小了。
这时候问题就来了,原本iPhone1只能看320像素宽的网页,超出320宽就得左右拖动着看。现在iPhone4可以看640像素宽的网页了,虽然是好事,但是640宽的页面挤在手机屏幕上看,字小的跟米粒一样,完全看不清。
这时候苹果就给出解决方案,就是著名的<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
,苹果此时提出了视口(viewport)的概念,苹果的想法是,你们程序猿们做网页就仍然按照320像素的宽度做,但是要加上这行代码,这时候iPhone 4给你们渲染页面的时候,按照四个像素顶一个像素的原则显示,就没问题了。但是如果你不听我的话,不加这样代码,就还是按照640像素的宽度显示。
这样做之后,屏幕显示字体的时候,老机型的大像素只能显示某种单色,而现在大像素切成了四个小像素,这四个像素可以显示4种不同单色,于是削弱了锯齿感,字体也就更清晰了,苹果的目的就达到了。
从此出现了几个概念
CSS pixels:顾名思义,他就是CSS和JS所理解的像素单位。它跟设备屏幕的像素没必然关系,比如windows的桌面显示器,当你修改显示器的硬件分辨率,或右击桌面修改分辨率,比如把1920的分辨率改成800分辨率,你会发现网页里的图形和字体变得傻大傻大的,同样的显示器,原本能显示全宽网页,现在只能显示半宽,也就是说CSS像素变大了。所以,CSS像素是可以被硬件和软件任意调节的单位。
这个单位既然我都说了是CSS和JS相关的,当然也是程序猿必须关注的单位。
device pixels:可以理解为设备像素,官方的解释是:显示屏幕的最小物理单位,每个dp包含自己的颜色、高宽等,不可再细分。这种像素是真实的物理存在的,你打开一个空白记事本,拿起放大镜观察屏幕,看到的一个个像素格,就是device pixels。它是不可变的,设备一旦造出来就不会变大小和数量。官方在产品说明书上写的1920x1080就是说的物理像素。
CSS pixels跟device pixels的关系:1个CSS像素占多少个物理像素是不确定的。厂商只能是推荐一个比例,你听话你就能做出完美效果,不听话就做不出完美效果。苹果自家的操作系统和任何APP都要遵守苹果硬件部门的这个规定。
比如iPhone 1,比例是1:1,一个CSS像素就是一个物理像素,直到iPhone3都是这样。这时候并没有推荐比例这回事,因为不用推荐。
到了iPhone4之后情况就不一样了,视网膜屏出现了,一个CSS像素占4个物理像素。直到iPhone 6都是如此。
到了iPhone 6 plus又不一样了,第一个不同是一个CSS像素占9个物理像素了,第二个不同是iOS最后多了一步缩放,把整体画面缩小了1.15倍。很难理解?没事,看下图:
总之,了解CSS像素跟设备像素的意义至少有两个:
再看到1920x1080这种官方文档里的分辨率的时候不用一脸懵逼:“什么鬼啊,怎么手机的分辨率比我电脑显示器的分辨率还要大啊!”
为下文打基础,下文所说的像素都是指CSS像素。
设备宽度(device-width):设备宽度是手机厂商给具体机型内定的一个值,从初代iPhone到5代,它的值都是320px。6代是375px,6plus是414px。这个值可以理解为标准分辨率或者推荐分辨率,就是说你的页面只要按照这个分辨率制作,厂商保证你得到完美效果。电脑显示器也有推荐分辨率,都是一样的道理。
程序猿想遵守推荐分辨率的话,就要在HTML中加上那行著名的<meta name="viewport" ...
,其中起作用的是width=device-width
这一句。
厂商规定device-width的好处不言而喻,如果不规定device-width,世界会是怎样?
- 要么就是程序猿业界对每一个设备都民间约定一个宽度
- 要么就是js判断某个参数,然后根据参数算出比较合理的宽度,这样等于js参与了“表现”,违背三分离原则
- 要么就是一律按照320px做,这样的话,手机越大,屏幕上的字和图就越大,在初代iPhone上看着挺好的字体,在最新iPhone上显得“傻大傻大”的
既然不规定device-width没有任何好处,所以你可以理解device-width的重要性了。
视口(viewport):是总概念,浏览器上(也可能是一个app中的webview)用来显示网页的那部分区域。业界认为,viewport分为3个子概念。这些子概念并不是什么官方组织规定的,而是一些先驱者总结出来的,如果某些文章并没有用这些概念或者概念解释有偏差,也是可能的。
布局视口(layout viewport):是分概念,当你没有设定那行著名代码的时候,厂商除了规定标准分辨率,还要给自己的手机设一个最大分辨率。想象一下,假如没有那行代码、也没有layout viewport,这时候你让手机打开一个5000像素宽的页面,那么手机会把5000宽度的页面全部挤到屏幕上,届时,每一个字将成为一个像素点,完全不可看。为了防止这种现象的出现,厂商规定了layout viewport,它的宽度可以通过
document.documentElement.clientWidth
来获取,通常都是980px,是一个固定值。为什么是这个数字呢,因为早期电脑显示器都是1024x768,当时的设计规范是给页面宽度设为980px,所以苹果也用了这个数字,到今天几乎所有厂商所有手机都是这个数字。这个数字对程序猿的意义其实不大,主要意义是厂商不至于让自家手机变得可笑,在打开大于980宽度的页面的时候可以横向拖动,而不至于挤成一团。视觉视口(visual viewport):是分概念,visual viewport的宽度可以通过window.innerWidth来获取。对于iPhone 6 Plus来说,在加了著名代码前提下,值是414px,不加的话,值是980px,著名代码如果改一改
width=device-width, initial-scale=1.5
,这时值是276px。所以它是一个可变的值。理想视口(ideal viewport):是分概念,顾名思义,就是当
width=device-width, initial-scale=1.0
的时候,视觉视口的大小。对于iPhone 6 Plus来说,是固定值414px。所以,理想视口就等于设备宽度。