像素

一个像素由红绿蓝三个像点组成,通过空间混色法显示颜色

点距:相邻同种颜色像点的距离

点距可以用来描述像素,点距越小,等距离的像素越多,显示越好。

分辨率

分辨率一般分为屏幕分辨率和图像分辨率。

屏幕分辨率:指一个屏幕具体由多少个像素点组成。

例如:iPhone XSMax 的分辨率为 2688x1242,表示手机分别在垂直和水平上所具有的像素点数为 2688 和 1242。

我们经常见到用 K 和 P 这个单位来形容屏幕:

  • P 代表的就是屏幕纵向的像素个数, 1080P 即纵向有 1080 个像素,分辨率为 1920X1080 的屏幕就属于 1080P 屏幕。
  • K 代表屏幕横向有几个 1024 个像素,一般来讲横向像素超过 2048 就属于 2K 屏,横向像素超过 4096 就属于 4K 屏。

我们平时所说的高清屏其实就是屏幕的物理分辨率达到或超过 1920X1080的屏幕。

图像分辨率:一般指的是一张图片含有的像素数。

例如:一张图片的分辨率为 800x400,这表示图片分别在垂直和水平上所具有的像素点数为 800和 400。

同一尺寸的图片,分辨率越高,图片越清晰。

PPI

PPI:每英寸包括的像素数,Pixel Per Inch

PPI 用于描述屏幕的清晰度以及一张图片的质量:

  • 使用 PPI 描述图片时, PPI越高,图片质量越高
  • 使用 PPI 描述屏幕时, PPI越高,屏幕越清晰

iPhone XSMax 和 iPhone SE 的 PPI 分别为 458 和 326,这足以证明 Phone XSMax 的屏幕更清晰。

DPI

DPI:即每英寸包括的点数,Dot Per Inch

这里的点是一个抽象的单位,它可以是屏幕像素点、图片像素点也可以是打印机的墨点。

DPI 可以用来描述图片和屏幕,此时 DPI 和 PPI 是等价的,DPI 一般用于描述打印机,表示打印机每英寸可以打印的点数。

一张图片在屏幕上显示时,它的像素点数是规则排列的,每个像素点都有特定的位置和颜色。 当使用打印机进行打印时,打印机可能不会规则的将这些点打印出来,而是使用一个个打印点来呈现这张图像,这些打印点之间会有一定的空隙,DPI所描述的就是打印点的密度。

打印机的 DPI越高,打印图像的精细程度就越高,同时这也会消耗更多的墨点和时间。

设备独立像素

随着科技的发展,低分辨率的手机已经不能满足需求,高分辨率屏幕就诞生了。

理论上来讲,320x480 分辨率手机上的图片和文字,在 640x940 分辨率手机上会被缩放为原来的1/4,而事实上我们现在使用的智能手机,不管分辨率多高,他们所展示的界面比例都是基本类似的。

乔布斯在 iPhone4 的发布会上首次提出了 RetinaDisplay 的概念,解决了这个问题,也使它成为一款跨时代的手机。

在 iPhone4 使用的视网膜屏幕中,把 2x2 个像素当 1 个像素使用,这样让屏幕看起来更精致,但是元素的大小却不会改变。

所以我们需要一种单位来告诉具有不同分辨率的手机,它们在界面上显示元素的大小是多少,这个单位就是设备独立像素 DeviceIndependentPixels,简称 DIP 或 DP

Chrome 开发者工具可以模拟各个手机型号的显示情况,每种型号上面会显示一个尺寸,该尺寸的单位就是设备独立像素。

比如:iPhone X 显示的尺寸是 375x812,实际 iPhone X 的分辨率 2436 x 1125 比这高很多,这里显示的就是设备独立像素。

设备像素比

设备像素比:物理像素设备独立像素的比值,device pixel ratio 简称 dpr

通过 window.devicePixelRatio 就可以获取设备的 dpr,在 CSS 中则可以使用媒体查询 min-device-pixel-ratio 区分不同的 dpr。

移动端开发中样式单位使用的都是设备独立像素,iOS的尺寸单位为 pt, Android的尺寸单位为 dp,它们其实都是设备独立像素 dp

UI 给我们的原型图一般是基于 iphone6 的像素给定的,为了适配我们在写样式时需要把物理像素转换为设备独立像素。

例如给定一个元素的高度为 200px (这里的 px 指物理像素), iphone6 的设备像素比为 2,我们给的高度应为 200px / 2 = 100dp

设计像素

iPhone6、7、8Plus 的物理像素是 1080x1920,在开发者工具中看到它们的设备独立像素是 414x736,设备像素比为 3,设备独立像素和设备像素比的乘积并不等于 1080x1920,而是等于 1242x2208。

实际上,手机会自动把 1242x2208 个像素点塞进 1080x1920 个物理像素点来渲染,我们不用关心这个过程。

而 1242x2208 被称为屏幕的设计像素,我们开发过程中也是以这个设计像素为准。

实际上,从苹果提出视网膜屏幕开始,才出现设备像素比这个概念,在这之前,移动设备都是直接使用物理像素来进行展示。

Android 同样使用了其他的技术方案来实现 DPR 大于 1的屏幕,不过原理是类似的。

由于 Android屏幕尺寸非常多、分辨率高低跨度非常大,不像苹果只有它自己的几款固定设备、尺寸。

各个设备的尺寸、分辨率上的差异,设备独立像素也不会完全相等,所以各种 Android 设备仍然不能做到在展示上完全相等。

CSS像素

CSS 认为浏览器中 1 CSS 像素的大小在不同物理设备上看上去大小总是差不多,所以 CSS 规范中使用参考像素来进行换算

参考像素: 一个 CSS 像素应当看起来是在距离观察者一臂之遥且像素密度为 96 DPI 的屏幕中的一个物理像素

通常认为常人臂长为28英寸,所以它的视角是:(1/96)in / (28in * 2 * PI / 360deg) = 0.0213度

所以 CSS 像素是一个视角单位,在真正实现时,为了方便基本都是根据设备像素换算的。

实际上默认情况下,一个 CSS 像素的大小等于一个设备独立像素

一般来说,PC 端在没有缩放(包括系统缩放和页面缩放)的情况下 1px = 1 物理像素,也就是 DPR = 1

但是 Mac 中内建了视网膜显示器,所以 DPR 一般不会为 1

CSS 像素的相对大小是很容易被改变的,当用户对浏览器进行了放大, CSS 像素的相对大小就会改变

页面的缩放系数 = CSS像素 / 设备独立像素

倍图

对于一张 100px * 100px 的图片,对尺寸进行设置:

1
2
3
4
img {
width: 100px;
height: 100px;
}

在普通显示屏的电脑中打开是正常的,但在 Retina 屏中打开,由于 dpr 为 2,就会拿 4 个物理像素来描绘 1 个电子像素

这等于拿一个 2 倍的放大镜去看图片,图片就会变得模糊

所以对于 Retina 屏幕,当 dpr > 1 时就不能使用原始分辨率的图片,所以就需要准备 2 倍图,3 倍图

视口

为了让给 PC 端设计的网页在移动端完整的显示,移动端中引入了 viewport 的概念

浏览器包含两个 viewport

  • 布局视口 (layout viewport)
  • 视觉视口 (visual viewport)

一般都认为移动设备还有第三个 viewport:idealviewport,可完美适配移动端的理想 viewport

当然这个视口应该指的是一个结果,是我们通过调节需要达到的视口状态,理想视口的值其实就是以设备独立像素为单位的宽度

布局视口

布局视口用于解决 PC 端页面在手机上显示的问题,iOS, Android 基本都将这个视口分辨率设置为 980px

通过 document.document.clientWidth 可以获取 layoutviewport 的宽度,要获取正确的值需要将设置视口的 meta 去掉

1
document.documentElement.clientWidth // 980

通过 meta 可以显示的设置布局视口的宽度:

1
<meta name="viewport" content="width=400">
1
document.documentElement.clientWidth	// 400

布局视口使得视口与移动端屏幕宽度完全独立开,CSS 布局将会根据它来进行计算

视觉视口

视觉视口是屏幕的可视部分,用户可以通过缩放操作视觉视口,同时不会影响布局视口。

当动态键盘在手机上弹出的时候,或者之前隐藏的地址栏变得可见的时候,visual viewport 缩小了, layout viewport 保持不变

视觉视口和缩放比例的关系为:

1
当前缩放值 = 理想视口宽度  / 视觉视口宽度

调节视口

通过设置 content=device-width 可以使得布局视口与理想视口的宽度一致

通过设置 initial-sacle=1 让布局视口宽度进行缩放,同样可以使得布局视口与理想视口的宽度一致