[TOC]
# 英寸
一般用英寸描述屏幕的物理大小,如电脑显示器的`17`、`22`,手机显示器的`4.8`、`5.7`等使用的单位都是英寸。
<br>
需要注意,上面的尺寸都是屏幕对角线的长度:

<br>
英寸(`inch`,缩写为`in`)在荷兰语中的本意是大拇指,一英寸就是指甲底部普通人拇指的宽度。
英寸和厘米的换算:`1英寸 = 2.54 厘米`
<br>
<br>
# 分辨率
## 像素
像素即一个小方块,它具有特定的位置和颜色。
<br>
图片、电子屏幕(手机、电脑)就是由无数个具有特定颜色和特定位置的小方块拼接而成。
<br>
像素可以作为图片或电子屏幕的最小组成单位。
<br>
通常我们所说的分辨率有两种,屏幕分辨率和图像分辨率。
<br>
## 屏幕分辨率
屏幕分辨率指**一个屏幕具体由多少个像素点**组成。
<br>
下面是`apple`的官网上对手机分辨率的描述:

<br>
`iPhone XS Max`和`iPhone SE`的分辨率分别为`2688 x 1242`和`1136 x 640`。这表示手机分别在垂直和水平上所具有的像素点数。
<br>
当然分辨率高不代表屏幕就清晰,屏幕的清晰程度还与尺寸有关。
<br>
## 图像分辨率
我们通常说的 **图片分辨率** 其实是指图片含有的`像素数`,比如一张图片的分辨率为`800 x 400`。这表示图片分别在垂直和水平上所具有的像素点数为`800`和`400`。
<br>
同一尺寸的图片,分辨率越高,图片越清晰。
<br>

## PPI
`PPI(Pixel Per Inch)`:每英寸包括的像素数。
<br>
`PPI`可以用于描述屏幕的清晰度以及一张图片的质量。
<br>
使用`PPI`描述图片时,`PPI`越高,图片质量越高,使用`PPI`描述屏幕时,`PPI`越高,屏幕越清晰。
<br>
在上面描述手机分辨率的图片中,我们可以看到:`iPhone XS Max` 和 `iPhone SE`的`PPI`分别为`458`和`326`,这足以证明前者的屏幕更清晰。
<br>
由于手机尺寸为手机对角线的长度,我们通常使用如下的方法计算`PPI`:

<br>
`iPhone 6`的`PPI`为: ,那它每英寸约含有`326`个物理像素点。
<br>
## DPI
`DPI(Dot Per Inch)`:即每英寸包括的点数。
<br>
这里的点是一个抽象的单位,它可以是屏幕像素点、图片像素点也可以是打印机的墨点。
<br>
平时你可能会看到使用`DPI`来描述图片和屏幕,这时的`DPI`应该和`PPI`是等价的,`DPI`最常用的是用于描述打印机,表示打印机每英寸可以打印的点数。
<br>
一张图片在屏幕上显示时,它的像素点数是规则排列的,每个像素点都有特定的位置和颜色。
<br>
当使用打印机进行打印时,打印机可能不会规则的将这些点打印出来,而是使用一个个打印点来呈现这张图像,这些打印点之间会有一定的空隙,这就是`DPI`所描述的:打印点的密度。
<br>

<br>
在上面的图像中我们可以清晰的看到,打印机是如何使用墨点来打印一张图像。
<br>
所以,打印机的`DPI`越高,打印图像的精细程度就越高,同时这也会消耗更多的墨点和时间。
<br>
<br>
# 设备独立像素
实际上,上面我们描述的像素都是 **物理像素**,即设备上真实的物理单元。
<br>
下面我们来看看 **设备独立像素** 究竟是如何产生的:
<br>
智能手机发展非常之快,在几年之前,我们还用着分辨率非常低的手机,比如下面左侧的白色手机,它的分辨率是`320x480`,我们可以在上面浏览正常的文字、图片等等。
<br>
但是,随着科技的发展,低分辨率的手机已经不能满足我们的需求了。很快,更高分辨率的屏幕诞生了,比如下面的黑色手机,它的分辨率是`640x940`,正好是白色手机的两倍。

理论上来讲,在白色手机上相同大小的图片和文字,在黑色手机上会被缩放一倍,因为它的分辨率提高了一倍。这样,岂不是后面出现更高分辨率的手机,页面元素会变得越来越小吗?
<br>
然而,事实并不是这样的,我们现在使用的智能手机,不管分辨率多高,他们所展示的界面比例都是基本类似的。乔布斯在`iPhone4`的发布会上首次提出了`Retina Display`(视网膜屏幕)的概念,它正是解决了上面的问题,这也使它成为一款跨时代的手机。
<br>
在`iPhone4`使用的视网膜屏幕中,把`2x2`个像素当`1`个像素使用,这样让屏幕看起来更精致,但是元素的大小却不会改变。
<br>

<br>
如果黑色手机使用了视网膜屏幕的技术,那么显示结果应该是下面的情况,比如列表的宽度为`300`个像素,那么在一条水平线上,白色手机会用`300`个物理像素去渲染它,而黑色手机实际上会用`600`个物理像素去渲染它。
<br>
我们必须用一种单位来同时告诉不同分辨率的手机,它们在界面上显示元素的大小是多少,这个单位就是设备独立像素(`Device Independent Pixels`)简称`DIP`或`DP`。上面我们说,列表的宽度为`300`个像素,实际上我们可以说:列表的宽度为`300`个设备独立像素。

打开`chrome`的开发者工具,我们可以模拟各个手机型号的显示情况,每种型号上面会显示一个尺寸,比如`iPhone X`显示的尺寸是`375x812`,实际`iPhone X`的分辨率会比这高很多,这里显示的就是设备独立像素。
<br>

<br>
## 设备像素比
设备像素比`device pixel ratio`简称`dpr`,即物理像素和设备独立像素的比值。
<br>
在`web`中,浏览器为我们提供了`window.devicePixelRatio`来帮助我们获取`dpr`。
<br>
在`css`中,可以使用媒体查询`min-device-pixel-ratio`,区分`dpr`:
~~~
@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){ }
~~~
<br>
在`React Native`中,我们也可以使用`PixelRatio.get()`来获取`DPR`。
<br>
当然,上面的规则也有例外,`iPhone 6、7、8 Plus`的实际物理像素是`1080 x 1920`,在开发者工具中我们可以看到:它的设备独立像素是`414 x 736`,设备像素比为`3`,设备独立像素和设备像素比的乘积并不等于`1080 x 1920`,而是等于`1242 x 2208`。
<br>
实际上,手机会自动把`1242 x 2208`个像素点塞进`1080 * 1920`个物理像素点来渲染,我们不用关心这个过程,而`1242 x 2208`被称为屏幕的`设计像素`。我们开发过程中也是以这个`设计像素`为准。
<br>
实际上,从苹果提出视网膜屏幕开始,才出现设备像素比这个概念,因为在这之前,移动设备都是直接使用物理像素来进行展示。
<br>
紧接着,`Android`同样使用了其他的技术方案来实现`DPR`大于`1`的屏幕,不过原理是类似的。由于`Android`屏幕尺寸非常多、分辨率高低跨度非常大,不像苹果只有它自己的几款固定设备、尺寸。所以,为了保证各种设备的显示效果,`Android`按照设备的像素密度将设备分成了几个区间:

<br>
当然,所有的`Android`设备不一定严格按照上面的分辨率,每个类型可能对应几种不同分辨率,所以,每个`Android`手机都能根据给定的区间范围,确定自己的`DPR`,从而拥有类似的显示。当然,仅仅是类似,由于各个设备的尺寸、分辨率上的差异,设备独立像素也不会完全相等,所以各种`Android`设备仍然不能做到在展示上完全相等。
<br>
## 移动端开发
在`iOS`、`Android`和`React Native`开发中样式单位其实都使用的是设备独立像素。
<br>
`iOS`的尺寸单位为`pt`,`Android`的尺寸单位为`dp`,`React Native`中没有指定明确的单位,它们其实都是设备独立像素`dp`。
<br>
在使用`React Native`开发`App`时,`UI`给我们的原型图一般是基于`iphone6`的像素给定的。
<br>
为了适配所有机型,我们在写样式时需要把物理像素转换为设备独立像素:例如:如果给定一个元素的高度为`200px`(这里的`px`指物理像素,非`CSS`像素),`iphone6`的设备像素比为`2`,我们给定的`height`应为`200px/2=100dp`。
<br>
当然,最好的是,你可以和设计沟通好,所有的`UI`图都按照设备独立像素来出。
<br>
我们还可以在代码(`React Native`)中进行`px`和`dp`的转换:
~~~
import {PixelRatio } from 'react-native';
const dpr = PixelRatio.get();
/**
* px转换为dp
*/
export function pxConvertTodp(px) {
return px / dpr;
}
/**
* dp转换为px
*/
export function dpConvertTopx(dp) {
return PixelRatio.getPixelSizeForLayoutSize(dp);
}
~~~
<br>
## WEB端开发
在写`CSS`时,我们用到最多的单位是`px`,即`CSS像素`,当页面缩放比例为`100%`时,一个`CSS像素`等于一个设备独立像素。
<br>
但是`CSS像素`是很容易被改变的,当用户对浏览器进行了放大,`CSS像素`会被放大,这时一个`CSS像素`会跨越更多的物理像素。
<br>
`页面的缩放系数 = CSS像素 / 设备独立像素`。
<br>
## 关于屏幕
`Retina`屏幕只是苹果提出的一个营销术语:
> 在普通的使用距离下,人的肉眼无法分辨单个的像素点。
<br>
为什么强调`普通的使用距离下`呢?我们来看一下它的计算公式:

<br>
`a`代表人眼视角,`h`代表像素间距,`d`代表肉眼与屏幕的距离,符合以上条件的屏幕可以使肉眼看不见单个物理像素点。
<br>
它不能单纯的表达分辨率和`PPI`,只能一种表达视觉效果。
<br>
让多个物理像素渲染一个独立像素只是`Retina`屏幕为了达到效果而使用的一种技术。而不是所有`DPR > 1`的屏幕就是`Retina`屏幕。
<br>
比如:给你一块超大尺寸的屏幕,即使它的`PPI`很高,`DPR`也很高,在近距离你也能看清它的像素点,这就不算`Retina`屏幕。
<br>

<br>
我们经常见到用`K`和`P`这个单位来形容屏幕:
<br>
`P`代表的就是屏幕纵向的像素个数,`1080P`即纵向有`1080`个像素,分辨率为`1920X1080`的屏幕就属于`1080P`屏幕。
<br>
我们平时所说的高清屏其实就是屏幕的物理分辨率达到或超过`1920X1080`的屏幕。
<br>
`K`代表屏幕横向有几个`1024`个像素,一般来讲横向像素超过`2048`就属于`2K`屏,横向像素超过`4096`就属于`4K`屏。
<br>
<br>
<br>
# 参考资料
[关于移动端适配,你必须要知道的](https://juejin.im/post/5cddf289f265da038f77696c)
- 第一部分 HTML
- meta
- meta标签
- HTML5
- 2.1 语义
- 2.2 通信
- 2.3 离线&存储
- 2.4 多媒体
- 2.5 3D,图像&效果
- 2.6 性能&集成
- 2.7 设备访问
- SEO
- Canvas
- 压缩图片
- 制作圆角矩形
- 全局属性
- 第二部分 CSS
- CSS原理
- 层叠上下文(stacking context)
- 外边距合并
- 块状格式化上下文(BFC)
- 盒模型
- important
- 样式继承
- 层叠
- 属性值处理流程
- 分辨率
- 视口
- CSS API
- grid(未完成)
- flex
- 选择器
- 3D
- Matrix
- AT规则
- line-height 和 vertical-align
- CSS技术
- 居中
- 响应式布局
- 兼容性
- 移动端适配方案
- CSS应用
- CSS Modules(未完成)
- 分层
- 面向对象CSS(未完成)
- 布局
- 三列布局
- 单列等宽,其他多列自适应均匀
- 多列等高
- 圣杯布局
- 双飞翼布局
- 瀑布流
- 1px问题
- 适配iPhoneX
- 横屏适配
- 图片模糊问题
- stylelint
- 第三部分 JavaScript
- JavaScript原理
- 内存空间
- 作用域
- 执行上下文栈
- 变量对象
- 作用域链
- this
- 类型转换
- 闭包(未完成)
- 原型、面向对象
- class和extend
- 继承
- new
- DOM
- Event Loop
- 垃圾回收机制
- 内存泄漏
- 数值存储
- 连等赋值
- 基本类型
- 堆栈溢出
- JavaScriptAPI
- document.referrer
- Promise(未完成)
- Object.create
- 遍历对象属性
- 宽度、高度
- performance
- 位运算
- tostring( ) 与 valueOf( )方法
- JavaScript技术
- 错误
- 异常处理
- 存储
- Cookie与Session
- ES6(未完成)
- Babel转码
- let和const命令
- 变量的解构赋值
- 字符串的扩展
- 正则的扩展
- 数值的扩展
- 数组的扩展
- 函数的扩展
- 对象的扩展
- Symbol
- Set 和 Map 数据结构
- proxy
- Reflect
- module
- AJAX
- ES5
- 严格模式
- JSON
- 数组方法
- 对象方法
- 函数方法
- 服务端推送(未完成)
- JavaScript应用
- 复杂判断
- 3D 全景图
- 重载
- 上传(未完成)
- 上传方式
- 文件格式
- 渲染大量数据
- 图片裁剪
- 斐波那契数列
- 编码
- 数组去重
- 浅拷贝、深拷贝
- instanceof
- 模拟 new
- 防抖
- 节流
- 数组扁平化
- sleep函数
- 模拟bind
- 柯里化
- 零碎知识点
- 第四部分 进阶
- 计算机原理
- 数据结构(未完成)
- 算法(未完成)
- 排序算法
- 冒泡排序
- 选择排序
- 插入排序
- 快速排序
- 搜索算法
- 动态规划
- 二叉树
- 浏览器
- 浏览器结构
- 浏览器工作原理
- HTML解析
- CSS解析
- 渲染树构建
- 布局(Layout)
- 渲染
- 浏览器输入 URL 后发生了什么
- 跨域
- 缓存机制
- reflow(回流)和repaint(重绘)
- 渲染层合并
- 编译(未完成)
- Babel
- 设计模式(未完成)
- 函数式编程(未完成)
- 正则表达式(未完成)
- 性能
- 性能分析
- 性能指标
- 首屏加载
- 优化
- 浏览器层面
- HTTP层面
- 代码层面
- 构建层面
- 移动端首屏优化
- 服务器层面
- bigpipe
- 构建工具
- Gulp
- webpack
- Webpack概念
- Webpack工具
- Webpack优化
- Webpack原理
- 实现loader
- 实现plugin
- tapable
- Webpack打包后代码
- rollup.js
- parcel
- 模块化
- ESM
- 安全
- XSS
- CSRF
- 点击劫持
- 中间人攻击
- 密码存储
- 测试(未完成)
- 单元测试
- E2E测试
- 框架测试
- 样式回归测试
- 异步测试
- 自动化测试
- PWA
- PWA官网
- web app manifest
- service worker
- app install banners
- 调试PWA
- PWA教程
- 框架
- MVVM原理
- Vue
- Vue 饿了么整理
- 样式
- 技巧
- Vue音乐播放器
- Vue源码
- Virtual Dom
- computed原理
- 数组绑定原理
- 双向绑定
- nextTick
- keep-alive
- 导航守卫
- 组件通信
- React
- Diff 算法
- Fiber 原理
- batchUpdate
- React 生命周期
- Redux
- 动画(未完成)
- 异常监控、收集(未完成)
- 数据采集
- Sentry
- 贝塞尔曲线
- 视频
- 服务端渲染
- 服务端渲染的利与弊
- Vue SSR
- React SSR
- 客户端
- 离线包
- 第五部分 网络
- 五层协议
- TCP
- UDP
- HTTP
- 方法
- 首部
- 状态码
- 持久连接
- TLS
- content-type
- Redirect
- CSP
- 请求流程
- HTTP/2 及 HTTP/3
- CDN
- DNS
- HTTPDNS
- 第六部分 服务端
- Linux
- Linux命令
- 权限
- XAMPP
- Node.js
- 安装
- Node模块化
- 设置环境变量
- Node的event loop
- 进程
- 全局对象
- 异步IO与事件驱动
- 文件系统
- Node错误处理
- koa
- koa-compose
- koa-router
- Nginx
- Nginx配置文件
- 代理服务
- 负载均衡
- 获取用户IP
- 解决跨域
- 适配PC与移动环境
- 简单的访问限制
- 页面内容修改
- 图片处理
- 合并请求
- PM2
- MongoDB
- MySQL
- 常用MySql命令
- 自动化(未完成)
- docker
- 创建CLI
- 持续集成
- 持续交付
- 持续部署
- Jenkins
- 部署与发布
- 远程登录服务器
- 增强服务器安全等级
- 搭建 Nodejs 生产环境
- 配置 Nginx 实现反向代理
- 管理域名解析
- 配置 PM2 一键部署
- 发布上线
- 部署HTTPS
- Node 应用
- 爬虫(未完成)
- 例子
- 反爬虫
- 中间件
- body-parser
- connect-redis
- cookie-parser
- cors
- csurf
- express-session
- helmet
- ioredis
- log4js(未完成)
- uuid
- errorhandler
- nodeclub源码
- app.js
- config.js
- 消息队列
- RPC
- 性能优化
- 第七部分 总结
- Web服务器
- 目录结构
- 依赖
- 功能
- 代码片段
- 整理
- 知识清单、博客
- 项目、组件、库
- Node代码
- 面试必考
- 91算法
- 第八部分 工作代码总结
- 样式代码
- 框架代码
- 组件代码
- 功能代码
- 通用代码