§ 2.1 · Section

像素与分辨率

Pixels & Resolution · The Smallest Unit of Everything

界面世界的原子是像素无论多精致的设计、多复杂的动画,最终都归结为一件事:给屏幕上每个小方格指定一个颜色。而"1 个像素到底多大"这个看似幼稚的问题,答案居然有三种——搞不清这三种,你就永远不明白为什么设计稿要给 @2x、@3x 三份图。

生活场景
🧵 十字绣、马赛克与体育馆的人浪

凑到很近看老式路边的 LED 广告牌,你会发现它其实是一颗一颗小灯泡,每颗灯泡只能亮一种颜色。走远了,眼睛把它们混在一起,就成了一幅完整的画。
体育馆里几万人举牌做出的"人浪图案"也是这个道理——每个人只负责举一块牌子(一个像素),图案是从远处看才出现的。
屏幕就是这样一块巨大的、极其精细的"举牌方阵"。你手机上大约有三百多万个"人"在同时举牌,而且每秒换 60 次姿势。

像素是什么:屏幕上最小的发光单元

把手机屏幕放到显微镜下看,你会看到一件出乎意料的事:一个像素其实不是一个点,而是三个挨在一起的小灯——一个红、一个绿、一个蓝。它们叫子像素(Subpixel)

为什么是红绿蓝这三个?因为人眼视网膜上正好有三种感知颜色的锥状细胞,分别对红、绿、蓝三段波长最敏感。所以只要用这三种光按不同比例混合,就能骗过人眼,让它"以为"看到了任何颜色。这套机制叫RGB 加色混合

每个子像素的亮度通常用 0 到 255 共 256 级来表示。于是一个像素能表达的颜色数量是 256 × 256 × 256 ≈ 1678 万种——这就是"1600 万色 / 24 位真彩色"的来历。

一个像素的内部构造与颜色计算

  ┌─────────────────┐
  │  R  │  G  │  B  │   ← 三个子像素,各 256 级亮度
  └─────────────────┘

  (255,   0,   0) → 纯红     :只有红灯全亮
  (255, 255,   0) → 黄色     :红 + 绿全亮(不是红+黄!加色混合反直觉)
  (255, 255, 255) → 白色     :三个全亮
  (  0,   0,   0) → 黑色     :三个全灭
  ( 85,107,  61) → 本站主色  :#556b3d

  可表达颜色数 = 256 × 256 × 256 = 16,777,216 种

这里有个值得注意的细节:纯黑在不同屏幕上不是一回事。液晶屏(LCD)的背光是常亮的,靠液晶层"挡光"来做黑,挡不干净,所以黑色其实是深灰。而 OLED 屏的每个子像素自己发光,要黑就直接断电不亮,那是真正的漆黑。这就是为什么 OLED 手机上的深色模式看起来特别"深",而且还更省电——黑色区域压根没通电。

子像素的排列方式也不止一种。常见的 LCD 是横向 RGB 条状排列,而三星的 OLED 常用"钻石排列"(Pentile),红蓝子像素数量少于绿色。这会导致同样标称分辨率下,文字边缘的细节表现略有差异——早年 Pentile 屏被批评"文字发虚",就是这个原因。

分辨率 vs 屏幕尺寸:两个完全不同的东西

这是新手最容易混的一对概念,也是买显示器时最容易踩的坑。

为什么必须分清?举个极端例子:一块 6 英寸的手机屏和一块 60 英寸的电视,分辨率可以完全一样,都是 1920 × 1080。像素数量一模一样,但手机看起来细腻锐利,电视凑近看能数出格子。

反过来也成立:一块 27 英寸的 1080p 显示器,和一块 24 英寸的 1080p 显示器,同样是 1080p,但 24 寸那块明显更清晰——因为同样多的像素被塞进了更小的面积里。

所以下次看到"高分辨率 = 高清"这种说法,要在心里补一句:决定清晰度的从来不是分辨率,而是分辨率与尺寸的比值

PPI / DPI:清晰度的真正指标

PPI(Pixels Per Inch,每英寸像素数)用于屏幕;DPI(Dots Per Inch,每英寸墨点数)本来是印刷术语,说的是打印机每英寸打多少个墨点。两者原理相通,日常口语里常混用,但严格来说:屏幕说 PPI,打印说 DPI

计算公式很简单——先用勾股定理算出对角线上有多少像素,再除以对角线的物理英寸数:

PPI = √(横向像素² + 纵向像素²) ÷ 屏幕对角线英寸

【例 1】iPhone 15:2556 × 1179,6.1 英寸
   对角线像素 = √(2556² + 1179²) = √(6533136 + 1390041) ≈ 2814
   PPI = 2814 ÷ 6.1 ≈ 461      → 非常细腻

【例 2】27 寸 1080p 显示器
   对角线像素 = √(1920² + 1080²) ≈ 2203
   PPI = 2203 ÷ 27 ≈ 82        → 凑近能看到颗粒

【例 3】27 寸 4K 显示器(3840 × 2160)
   对角线像素 = √(3840² + 2160²) ≈ 4406
   PPI = 4406 ÷ 27 ≈ 163       → 清晰,接近"视网膜"标准

那么多少 PPI 才算够?这里的关键是观看距离。人眼的角分辨力大约是 1 弧分,换算下来:手机通常在 25~30 厘米处使用,需要 300 PPI 以上才看不出颗粒;笔记本在 50 厘米左右,200 PPI 左右就够;电视在 3 米开外,50 PPI 都足够。

这解释了一个常见疑问:为什么 8K 电视看起来提升不大?因为在正常客厅的观看距离上,你的眼睛已经分辨不出 4K 和 8K 的差别了——不是屏幕不够好,是眼睛的采样率不够。

Analogy · 一斤糖,撒在盘子上还是撒在操场上

把像素想成一袋糖粉
分辨率 = 糖粉有多少粒;屏幕尺寸 = 要撒到多大面积上;PPI = 撒完以后每平方厘米有多少粒。
同样一袋糖,撒在小盘子上密密实实看不出颗粒(高 PPI);撒到操场上就稀稀拉拉,一眼能数出粒(低 PPI)。
所以"这块屏清晰吗"这个问题,光问"多少粒糖"是没有答案的——必须同时知道"撒多大"。

物理像素 vs 逻辑像素:一个 px 到底多大

现在到了本节最核心、也最容易让人困惑的地方。

假设你在 CSS 里写 width: 100px。在 2010 年之前,这句话的意思很朴素:占 100 个真实的屏幕像素。但当手机 PPI 冲到 400 以上后,这个逻辑彻底崩了——如果 100px 还是 100 个物理像素,那么一个手机上的按钮会小到只有几毫米,根本按不到。

于是业界引入了一层抽象,把"像素"这个词拆成了两个概念:

概念别称含义谁在用
物理像素设备像素 / Device Pixel屏幕上真实存在的那颗发光单元,硬件出厂就定死了硬件、驱动、渲染最底层
逻辑像素CSS px / DIP / pt / dp一个抽象的长度单位,约定为"在标准观看距离下看起来差不多大",与硬件解耦开发者写代码、设计师出稿

换句话说,CSS 里的 px 从来就不是"一个屏幕像素",它是一个视觉长度单位。W3C 的规范里把 1 个 CSS px 定义为在标准观看距离下约等于 1/96 英寸的视角大小。它更像"厘米",而不像"一颗灯泡"。

各平台给这个抽象单位起了不同名字,但说的是同一件事:Web 叫 CSS px,Android 叫 dp(density-independent pixel),iOS 叫 pt(point),Windows 叫 DIP。你写 44dp44pt,在任何设备上摸起来都差不多大——系统会自动换算成对应数量的物理像素。

这层抽象带来的好处极大:你不再需要关心用户的屏幕有多密。你按"看起来该多大"来写代码,系统负责翻译。这跟你订做衣服时说"腰围 75 厘米"而不是"75 根纤维宽"是一个道理。

设备像素比 DPR:两套像素之间的汇率

既然有两套像素,就必须有一个换算比率。这个比率叫设备像素比(Device Pixel Ratio,DPR)

DPR = 物理像素数 ÷ 逻辑像素数

【普通显示器】DPR = 1
   1 个逻辑像素  →  1 个物理像素        (一对一)

【iPhone / Retina 笔记本】DPR = 2
   1 个逻辑像素  →  2×2 = 4 个物理像素   (一个格子里塞四颗灯)

【高端安卓旗舰】DPR = 3
   1 个逻辑像素  →  3×3 = 9 个物理像素   (一个格子里塞九颗灯)

// 在浏览器里查看当前设备的 DPR:
console.log(window.devicePixelRatio);   // 1、2、2.75、3 ...

// 逻辑分辨率(你写代码面对的) vs 物理分辨率(屏幕真实的)
console.log(window.innerWidth);            // 例如 393(逻辑)
console.log(window.innerWidth * window.devicePixelRatio);  // 例如 1179(物理)

这解释了一个让很多人困惑的现象:iPhone 15 的屏幕物理分辨率是 1179 × 2556,但你在 CSS 里拿到的宽度只有 393。因为 1179 ÷ 3 = 393——它的 DPR 是 3,三个物理像素排成一行才算一个逻辑像素。

注意 DPR 不一定是整数。很多安卓机是 2.625、2.75 这类小数,Windows 的缩放设置里选 125%、150% 也会得到 1.25、1.5。小数 DPR 是渲染问题的重灾区——1 逻辑像素的细线要画成 1.5 个物理像素,画不出半颗灯,只能靠灰度模糊来近似,于是细线看起来发虚。这就是老前端常抱怨的"1px 边框问题"。

Retina 屏原理与 @2x / @3x 图

2010 年苹果推出 iPhone 4 时提出了 Retina(视网膜屏)这个营销词,它的技术含义就一句话:PPI 高到在正常使用距离上人眼分辨不出单个像素

但苹果做的最聪明的一件事不是提高 PPI,而是同时把逻辑像素数保持不变。iPhone 3GS 是 320×480 物理像素,iPhone 4 变成 640×960 物理像素,但逻辑尺寸仍然是 320×480。结果是:所有老 App 不用改一行代码,按钮和文字还是原来那么大,只是每一个逻辑像素现在由四颗灯来显示,边缘变得极其平滑

这个策略的代价,落在了图片身上。

文字和矢量图形无所谓——它们是靠数学公式实时绘制的,DPR 多大就按多大精度画,天生清晰。但位图(PNG / JPG)里的像素是死的。一张 100×100 的图片,在 DPR=2 的屏幕上要占据 200×200 个物理像素,系统只能把每个原始像素拉大成四个——于是变糊。

解决办法就是准备多套图:

文件名实际像素尺寸适用 DPR显示出来的逻辑尺寸
icon.png100 × 1001(普通屏)100 × 100
icon@2x.png200 × 2002(Retina)100 × 100
icon@3x.png300 × 3003(安卓旗舰)100 × 100

注意最后一列:三张图显示出来一样大,区别只在于高 DPR 屏幕上用的那张有更多真实像素可供利用,所以更清晰。这就是设计师交付时总要导出三份的原因——不是为了让图变大,而是为了喂饱那些密集的灯泡。

<!-- 让浏览器根据 DPR 自动挑选合适的图 -->
<img src="icon.png"
     srcset="icon.png 1x, icon@2x.png 2x, icon@3x.png 3x"
     width="100" height="100" alt="图标">

/* CSS 里的写法 */
.logo { background-image: url(logo.png); }
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .logo { background-image: url(logo@2x.png); background-size: 100px 100px; }
}

同样的道理也适用于 <canvas>。画布的默认物理像素数等于 CSS 尺寸,在 Retina 屏上画出来的东西是糊的,必须手动把画布的实际像素放大 DPR 倍,再把绘图坐标系缩放回来:

// Canvas 高清适配:三行标准操作
const dpr = window.devicePixelRatio || 1;
canvas.width  = cssWidth  * dpr;     // 实际像素放大
canvas.height = cssHeight * dpr;
canvas.style.width  = cssWidth  + 'px';   // 显示尺寸保持不变
canvas.style.height = cssHeight + 'px';
ctx.scale(dpr, dpr);                 // 坐标系缩回来,后面照常用逻辑坐标画

开发中的六条实用建议

为什么这一节必须放在第 2 章开头

因为像素是本章后面所有内容的计量单位

下一节讲位图和矢量的差别,本质就是"存像素值"还是"存绘制指令";讲颜色,就是给每个像素的 RGB 三个通道赋值;讲渲染管线,就是"如何高效地算出每个像素该是什么颜色";讲 60fps,就是"这几百万个像素必须在 16.7 毫秒内全部算完并送屏"。

把像素、分辨率、PPI、逻辑像素、DPR 这五个概念的关系理清了,后面四节都会顺理成章。而没理清的话,你会一直被"为什么我的图在这台机器上是糊的"这类问题反复困扰,却始终找不到病根

Recap · 收束

像素是屏幕上能被独立控制颜色的最小单元,内部由 RGB 三个子像素组成,各 256 级,合计约 1678 万色。
分辨率(像素个数)与屏幕尺寸(物理英寸)是两个独立的量,两者相除得到的 PPI 才决定清晰度;公式是 √(横²+纵²) ÷ 对角线英寸。
"像素"这个词有两种含义:硬件上真实存在的物理像素,和开发者使用的抽象长度单位逻辑像素(CSS px / dp / pt)。两者的换算比率叫 DPR
Retina 屏的做法是提高物理像素密度、同时保持逻辑尺寸不变,于是文字和矢量自动变清晰,而位图必须准备 @2x / @3x 才不糊。
实践底线三句话:图标用 SVG、布局用逻辑像素、位图配 srcset

☰ 主页
学海无涯 · 界面篇 · § 2.1