当我们在讨论设备像素比(device pixel ratio,dpr)的时候我们在讨论什么?

2023-11-15

0. 为什么要写这篇文章?

最近查阅了一些移动端适配的文章和资料,对大多数的概念和论述没发现有疑惑的地方,唯独对设备像素比(device pixel ratio,dpr)有些不解,而设备像素比对理解移动端概念以及适配都起到重要作用,所以做了更多的资料查阅和理解,这期间花了一些时间,也希望有不同意见的同学可以交流一下
ps:这篇文章不是移动端适配入门文章,不对大多数基础概念进行解释,例如像素,viewport,meta标签和主流适配方案等,如果还没了解基础概念,建议读一下相关文章再来看(也可以先阅读我下面列出的参考文章,自己先理解一下 ^ _ ^)

1. 设备像素比的问题在哪里?

1.1. 不同的论述导致不同的理解

实际上,我在查阅文章的时候,发现不同文章对这个概念的论述存在差异性,而这个差异性容易导致理解的差异,大致可以归类为两种结论:
结论1:设备像素比 = 设备物理像素/设备独立像素

参考文章1:关于移动端适配,你必须要知道的
参考文章2:面试官:你了解过移动端适配吗?
参考文章3:移动前端开发之viewport的深入理解
参考文章4:使用Flexible实现手淘H5页面的终端适配
参考文章5:设备像素比devicePixelRatio简单介绍
参考文章6:what exactly is device pixel ratio?

结论2:设备像素比 = 设备物理像素/CSS像素

参考文章7:2022 年移动端适配方案指南
参考文章8:作为前端,你应该了解的分辨率/逻辑像素/物理像素/retina屏知识
参考文章9:完全理解px,dpr,dpi,dip
参考文章10:前端涉及的各种像素概念以及 viewport 汇总

设备像素比在浏览器下可以用window.devicePixelRatio接口获取,MDN是这样定义的:Window 接口的devicePixelRatio返回当前显示设备的物理像素分辨率与CSS像素分辨率之比。 此值也可以解释为像素大小的比率:一个CSS像素的大小与一个物理像素的大小。 简单来说,它告诉浏览器应使用多少屏幕实际像素来绘制单个CSS像素。

根据此定义,CSS像素是可变的,设备像素比应该也是可变的,所以结论2比较准确,但是还有一个可能,有没有可能设备独立像素就是相当于CSS像素呢?若是,则结论1也可以成立。下面继续讨论

1.2. 设备独立像素与CSS像素

综合分析1.1.节的参考文章,首先明确一个基本没有争议的结论:CSS大小是可变的,跟缩放有关。但关于设备独立像素与CSS像素的关系,有如下两种结论:

结论3:设备独立像素为固定值,与css像素成缩放比例的关系,见: 参考文章1参考文章4参考文章5参考文章6参考文章7参考文章9

结论4:设备独立像素就是css像素,见:参考文章3参考文章8参考文章10

我们回到设备独立像素出现的背景,设备独立像素是随着Retina屏的诞生而出现的,下面是apple开发网站的尺寸标注:
在这里插入图片描述

px是设备物理像素,pt是设备独立像素,@x等于 设备物理像素/设备独立像素,在chrome开发工具,adobedpi.lvmydevice.io等网站也可以看到类似的标注
在这里插入图片描述

由此可见,设备独立像素是一个与设备物理像素相对应的抽象尺寸标准,应该是不可变的,设备物理像素/设备独立像素的比值衡量的是设备在初始状态下(无缩放,缩放比例100%)用程序绘制一个抽象像素需要使用多少真实的像素,而无缩放的状态下,CSS像素是可以等价于设备独立像素的,在有缩放的状态下,缩放比例就是CSS像素与设备独立像素的比值,所以我们可以得出结论3(设备独立像素为固定值,与css像素成缩放比例的关系)是正确的

PPK在iPhone 4到来之前写了一篇文章,有一段话是这么描述的:

When the zooming factor is exactly 100%, one CSS pixel equals one device pixel (though the upcoming intermediate layer will take the place of device pixels here.)
当缩放因子等于100%的时候,一个CSS像素等于一个设备像素(尽管在即将到来的中间层会取代这里的设备像素

注意括号里面的话,即将到来的中间层也就是后面出现的设备独立像素的概念,也就是设备独立像素对标的是原来的设备物理像素,例如原来说在300%缩放的情况下1个CSS像素等于3个设备物理像素,以后就要说成1个CSS像素等于3个设备独立像素了,PPK这段话也间接印证了结论3

1.3. 小结

我们再回顾一下1.1.和1.2.得出的结论:

结论1:设备像素比 = 设备物理像素/设备独立像素
结论2:设备像素比 = 设备物理像素/CSS像素
结论3:设备独立像素为固定值,与css像素成缩放比例的关系
结论4:设备独立像素就是css像素

综合结论2和结论3,可以得出
结论5:设备像素比 = 设备物理像素/CSS像素;而设备独立像素为固定值,在无缩放的时候与CSS像素等价

而且你会发现,结论1和结论4只是结论5的在无缩放条件下的特例

另外,设备物理像素/设备独立像素,如果非要用一个词来指代,我觉得使用apple官网的scale factor(缩放因子)来描述挺合适的,即 scale factor=设备物理像素/设备独立像素,该值不可变

High-resolution displays have a higher pixel density, offering a scale factor of 2.0 or 3.0 (referred to as @2x and @3x).

2. 设备像素比 = 设备物理像素/CSS像素,真的正确吗?

好了,有了1.3.小结的结论,我们满怀欣喜地带着这个结论继续往前走

2.1. PC端验证

无缩放状态下:
设备像素比2,然后是各个宽度:设备独立像素1500,布局视口1500,测试元素宽度200,可反推出设备物理像素3000
基于无缩放状态下的数值,测试200%和50%缩放的数值,以下是我们的预期数值

缩放 设备像素比 设备独立像素 布局视口 测试元素
100% 2 1500 1500 200
200%(期望值) 4 1500 750 200
50% (期望值) 1 1500 3000 200

实际数据,见下图
在这里插入图片描述
数值符合预期,设备像素比 = 设备物理像素/CSS像素 通过验证

2.2. 手机端验证

使用iPhone6作为测试机型,iPhone6的设备独立像素为375 x 667,设备物理像素为750 x 1334,缩放因子为2

无缩放状态下:
设备像素比2,然后是各个宽度:设备独立像素375,布局视口375,测试元素宽度200,可反推出设备物理像素750
基于无缩放状态下的数值,测试200%和50%缩放的数值,缩放数值通过<meta name="viewport" content="width=device-width, initial-scale=1">标签的 initial-scale属性设置,以下是我们的预期数值

缩放 设备像素比 设备独立像素 布局视口 测试元素
100% 2 375 375 200
200%(期望值) 4 375 375 200
50% (期望值) 1 375 750 200

实际数据,见下图
在这里插入图片描述
真机效果
在这里插入图片描述

数值符合…等等,数据好像不符合预期?!

缩放 设备像素比 设备独立像素 布局视口 测试元素
100% 2 375 375 200
200%(期望值) 4 2 375 375 200
50% (期望值) 1 2 375 750 200

在手机端,设备像素比没有随着缩放比而变化?

2.3. 出了什么问题?

我们来看看出了什么问题,根据公式设备像素比 = 设备物理像素/CSS像素 ,设备物理像素不变,在3种缩放比例下,我们可以看到测试像素的CSS宽度均为200不变,而测试像素实际大小已发生了变化,说明CSS像素随着缩放覆盖了更多/更少的设备独立像素/设备物理像素,根据上面的公式,设备像素比是应该按预期发生变化的,然鹅,现在我们只在PC端看到了我们预期,在移动端设备像素比似乎不随缩放发生变化

再回过头来看看1.1.节关于MDN对设备像素比的定义:Window 接口的devicePixelRatio返回当前显示设备的物理像素分辨率与CSS像素分辨率之比。 此值也可以解释为像素大小的比率:一个CSS像素的大小与一个物理像素的大小。 简单来说,它告诉浏览器应使用多少屏幕实际像素来绘制单个CSS像素。

以上定义跟我们目前的认知一致,仍然没办法解释为什么移动端设备像素比不随缩放发生变化

2.4. 重新认识设备像素比

对于2.3.节出现的问题,困扰了我一段时间,直到我找到了一份window.devicePixelRatio的规范,如下:

The devicePixelRatio attribute must return the result of the following determine the device pixel ratio algorithm:

  1. If there is no output device, return 1 and abort these steps.
  2. Let CSS pixel size be the size of a CSS pixel at the current page zoom scale factor and at a pinch zoom scale factor of 1.0.
  3. Let device pixel size be the vertical size of a device pixel of the output device.
  4. Return the result of dividing CSS pixel size by device pixel size.

从第4点来看,window.devicePixelRatio返回的结果是CSS像素大小与设备物理像素大小之比,这和我们的公式设备像素比 = 设备物理像素/CSS像素 是一致的(注意,我们公式的像素单位是个数,规范第4点的单位是大小,所以除数和被除数会相反,但表达的意思是一致的)

既然结论没有问题,那是不是可能我们忽略了结论成立的某些前提条件,我们留意到规范第2点:

  1. Let CSS pixel size be the size of a CSS pixel at the current page zoom scale factor and at a pinch zoom scale factor of 1.0.
    使CSS像素大小为当前page zoom的缩放比例且pinch zoom缩放比例等于1之下的CSS像素大小

在这里,我们获悉了之前对设备像素比的定义中都没有提到的前提条件:
条件1:计算当前page zoom的缩放比例
条件2:使pinch zoom缩放比例等于1,换句话说,就是不计算page zoom的缩放比例

这两个条件其实给我们澄清了两种缩放:page zoom也就是页面缩放(例如在PC端使用Ctrl+鼠标滚轮/+/-),pinch zoom是手势缩放或者双指缩放。为什么计算设备像素比的时候要计算page zoom而不计算pinch zoom呢?有何区别呢?zoom的规范是这么说的

There are two kinds of zoom, page zoom which affects the size of the initial viewport, and pinch zoom which acts like a magnifying glass and does not affect the initial viewport or actual viewport.
存在两种缩放:会影响初始视口的页面缩放,和类似放大镜一样不会影响初始或实际视口的手势缩放

可对页面缩放和手势缩放可以得出如下结论:
结论6: 页面缩放会影响页面的布局视口,会引起页面的重新布局,所以设备像素比需计算页面缩放的比例
结论7: 手势缩放不会影响布局视口,不会引起页面重新布局,只会影响视觉视口,类似放大镜的功能,所以设备像素比不需计算手势缩放的比例,在计算设备像素比的时候CSS像素大小按照手势缩放比为1的大小计算

结论6已经在2.1.节验证了,为了验证结论7,我们利用笔记本的触摸板,来模拟实际设备的手势缩放(pinch zoom)功能(带触摸屏功能的电脑也可以直接在屏幕上操作)

PC端
在这里插入图片描述
移动端
在这里插入图片描述
可以看到,无论在PC端还是手机端,手势缩放不会影响布局视口,只会影响视觉视口,在只改变手势缩放的条件下,设备像素比保持不变,结论6验证通过

至此,对于2.2.和2.3.出现的问题:在移动端设备像素比不随缩放发生变化,也随着结论5和结论6的确定而解决了,因为移动端进行的是手势缩放(pinch zoom)而非页面缩放(page zoom),故设备像素比保持不变

ps:有意思的是,现在移动端浏览器似乎没有给我们提供类似PC端页面缩放的功能而只有手势缩放功能,也就意味着移动端的设备像素比在目前是可以“保持不变的”,也就意味着移动端在某种程度上,结论1(设备像素比 = 设备物理像素/设备独立像素)和结论4(设备独立像素就是css像素)确实是可以成立的,但如果没弄清楚为什么,就很容易造成概念和结论的混淆。而且谁也说不定哪一天移动端会不会有类似页面缩放(page zoom)的功能,万一呢?^ _ ^

3. 总结

根据结论5,6,7,有:
结论5:设备像素比 = 设备物理像素/CSS像素,而设备独立像素为固定值,在无缩放的时候与CSS像素等价
结论6: 页面缩放会影响页面的布局视口,会引起页面的重新布局,所以设备像素比需计算页面缩放的比例
结论7: 手势缩放不会影响布局视口,不会引起页面重新布局,只会影响视觉视口,类似放大镜的功能,所以设备像素比不需计算手势缩放的比例,在计算设备像素比的时候CSS像素大小按照手势缩放比为1的大小计算

把上面的3个结论总结到一起,可以得出对设备像素比的最终结论

设备像素比 = 设备物理像素/CSS像素,CSS像素的实际大小只受页面缩放(page zoom)的影响而不受手势缩放(pinch zoom)的影响;设备独立像素为固定值,在无缩放的时候与CSS像素等价

以上就是我查阅相关资料并逐步理清疑惑的过程,欢迎多多交流

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当我们在讨论设备像素比(device pixel ratio,dpr)的时候我们在讨论什么? 的相关文章

  • 响应式网格布局框架[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • css 计数器在 Internet Explorer 中无法工作以获取隐藏内容 - 如何修复?

    我们想要一些编号列表 并发现了这个很酷的计数器 您可以在 css 中使用它来让浏览器为您计算数字 ol instructions counter reset instructions section ol instructions gt l
  • 如何在 Bootstrap 3 中指定行高?

    使用 Bootstrap 3 我将 row 类的高度设置为 3 5em 我在行中有几个输入 它们与行的顶部对齐 我想让它们底部对齐 我尝试过垂直对齐 底部的样式 但这似乎不起作用 我想让东西底部对齐的原因是我有一个浮动标签 我在输入字段上方
  • gwt 中的垂直居中

    如何使用垂直面板在 gwt 中垂直居中 或者请告诉我有什么方法可以进行垂直居中 如果你想直接使用VerticalPanel从代码中 您需要使用setVerticalAlignment HasVerticalAlignment ALIGN M
  • CSS - 第一个没有特定类别的孩子

    是否可以编写一个 CSS 规则来选择没有特定类的元素的第一个子元素 example div span class common class ignore span span class common class ignore span sp
  • 由于绝对定位的抽屉,移动键盘可以向上推内容

    我正在制作一个带有 3 个抽屉的网站 元素绝对位于屏幕外 一个在左侧 一个在右侧 一个在底部 看看这里的网站 看看我在说什么https sjbuysse github io javascriting index html https sjb
  • 使下划线 CSS 过渡改变方向

    我正在使用我找到的一些风格这个网站 http callmenick com post simple css3 transitions transforms animations compilation创建有效的下划线幻灯片 请参见jsfid
  • 数据库中的 HTML 标签是不好的做法还是好的做法?

    有时我需要格式化来自数据库的特定数据或部分数据 例如 如果我有这样的 desc 存储在数据库中 HTML 4 经过调整 延伸和增强 超出了其最初的范围 为网站带来了高水平的交互性和多媒体 Flash Silverlight 和 Java 等
  • CSS:应用于类组合的样式?

    我不确定这是否可行 但是当您想根据应用于元素的类的组合来设置元素的样式时 是否可以在 CSS 中使用语法 我知道我可以使用 jQuery 或其他东西检查元素并根据它所具有的类更改它的样式 但是有没有一种纯 CSS 方法可以做到这一点 例如
  • 为什么我的字体大小在 android webview 对象中看起来比在 android 浏览器中查看时大得多?

    我正在尝试制作一个小型 Android 应用程序 它除了在 webview 对象而不是浏览中显示网站之外什么也不做 到目前为止它加载了目标网页 但文本和图像大小都比查看页面时大得多在实际设备浏览器中 在浏览器中 页面看起来正确 但在我的应用
  • App_offline.htm、CSS、图像和 aspnet_isapi.dll

    因此 我正在开发的网站正在使用 urlrewriting 与 aspnet isapi dll 配合 所有内容都映射到它 我放置了 app offline htm 文件 所有文本均显示 但是 CSS 或图像未提供 我猜测由于通配符映射而不是
  • 在 Chrome 中使用 webkit-transform 旋转时出现不稳定的文本抗锯齿效果

    我正在使用旋转元素 webkit transform rotate 在 Chrome 14 0 835 2 dev m 中 它对元素内的文本做了一些非常奇怪的事情 它让我想起了在 Photoshop 中使用 平滑 抗锯齿而不是 清晰 旋转文
  • Flexbox 调整大小和可滚动溢出[重复]

    这个问题在这里已经有答案了 我有正在调整大小的内容 并且我想要一个固定标题 该标题不会增大 缩小 并且不属于可滚动内容的一部分 如果空间不足 下面的内容将变得可滚动 内容外包装 flexGrowWrapper has a flex grow
  • 如果 CSS 是渲染阻塞的,为什么我们会看到 FOUC?

    为了构建渲染树 浏览器需要 DOM 和 CSSOM CSSOM 只有在下载 CSS 后才能构建 本质上 一旦下载了 CSS 页面就应该可以正常渲染了 但是 为什么我们会在页面上看到 Flash Of Unstyled Content FOU
  • 在 UIWebView 中禁用复制和粘贴

    几乎 我已经尝试了一切方法来禁用复制 粘贴UIWebView但对我来说没有任何作用 我正在加载我的UIWebView来自字符串 字符串数组 如下所示 webView loadHTMLString NSString stringWithFor
  • 为什么我不能同时使用背景图像和颜色?

    我想做的是展示两者background color and background image 这样我的一半div将覆盖右侧的阴影背景图像 而左侧的另一部分将覆盖背景颜色 但是当我使用background image 颜色消失 完全可以使用颜
  • 删除下拉链接并在导航栏菜单中显示其所有项目

    我正在使用 Twitter Bootstrap 及其响应式设计来实现顶部典型的 Twitter Bootstrap 导航栏菜单 在那里我有一些链接和一个下拉菜单 当我将浏览器大小调整为768px或者更少 它会转变为一种新的导航菜单 这一切开
  • 悬停时的 CSS 过渡

    我有个问题 实际上 当我将鼠标悬停在对象上时 我尝试在 div 上进行转换 所以基本上我有一个div 当我将鼠标悬停在div上时 它应该在其顶部显示另一个div 但是它应该被转换 这样悬停效果会更平滑 如果我有这两个 div 怎么可能 di
  • 伪元素的元素类型是什么?

  • 标题的下边框小于宽度

    我需要创建一个下划线效果底部边框小于h2标题的宽度 通常我不上传图片 但我认为这可能有助于进一步解释问题 您可以为此使用伪元素 例子 http jsfiddle net SZ39x pseudo border position relati

随机推荐

  • Linux Top 命令指南

    top 命令允许用户监视 Linux 上的进程和系统资源使用情况 它是系统管理员工具箱中最有用的工具之一 并且在每个发行版中都预装了它 与 ps 等其他命令不同 它是交互式的 我们可以浏览进程列表 终止进程 等等 本文中 我们将了解如何使用
  • 倾斜摄影三维模型五种常见格式

    在倾斜摄影三维数据中 OSGB数据居多 航拍的影像经过建模软件处理产出之时 有很多成果的数据需要我们去选择输出 对于不同的项目需求 我们需要选择合适的输出数据格式 他们之间有什么区别 分别是应用在哪些个领域 今天分别以OSGB OBJ FB
  • ipsec.conf(5) - Linux man pag 中文翻译

    ipsec conf 5 Linux man page 英文网址 https linux die net man 5 ipsec conf 未经许可 禁止转载 请知悉 Name 名称 ipsec conf IPsec配置和连接 Descri
  • Java内存分配介绍

    Java内存分配为 栈 堆 方法区 本地方法栈和寄存器 字节码文件加载时进入的内存方法区 方法运行区域为栈 变量也是存储在栈中 new出来的东西会在堆内存中开辟空间并产生地址 public class ArrayDemo public st
  • esp8266-12f介绍与使用

    nodemcu 体积相对较大 而且价格也相对较高 这时候 esp12f就可以用来代替 使用 nodemcu v2 v3 使用的是esp12e 与esp12f只有布线上有所差别 是esp8266 12的增强版 esp 12F 引脚图 各个引脚
  • 成员函数在类外定义的时候,函数名为啥不能加static

    今天清理手机微信没用的数据 惊人啊 删了1G 的图 再删删其它没用的数据 腾出来3G 的空间 无意间发现了一张以前聊天时候的图 回忆了一下 当时讨论的是 为啥成员函数在类外定义时 函数名不能加static class Point publi
  • (一)python库httprunner4 用法

    4个命令 httprunner V httprunner h hrun xxx 运行yaml json pytest 会内部执行hmake hmake xxx 把yaml json格式转成pytest测试用例 一个yaml用例结构 由一个c
  • 服务器查看系统盘位置,云服务器ecs怎么查看系统盘

    云服务器ecs怎么查看系统盘 内容精选 换一换 本节介绍将Windows操作系统的KVM实例变更为擎天架构实例的操作步骤 KVM实例 参考规格清单 查询对应规格的虚拟化类型 擎天架构实例 选择 通用计算增强型C7 变更规格时不支持修改网络类
  • 小样本目标检测综述 --刘浩宇,王向军 --阅读笔记

    文章目录 1 基本背景 2 大样本与小样本的对比 3 在没有大量数据支持的情况下 小样本检测保证检测效果 有哪些解决方法 3 1 数据域 3 1 1 转化原有数据集 D t D t
  • Intel编译器的强大pragma:unroll_and_jam()/nounroll_and_jam()

    Intel官方文档 Hints to the compiler to enable or disable loop unrolling and jamming These pragmas can only be applied to ite
  • Vim快速移动光标至行首和行尾 、第一行和最后一行

    vi中跳到文件的第一行和最后一行 由于vi编辑器不能使用鼠标 所以一个大文件如果要到最后一行只用键盘下键的话会是一个很痛苦的过程 还好有各种比较快捷的方法归我们使用 1 vi 编辑器中跳到文件的第一行 a 输入 0 或者 1 回车 b 键盘
  • 如何一次性选中WORD文档中的所有表格

    1 将下面的脚本复制 Sub SelectAllTables Dim tempTable As Table Application ScreenUpdating False 判断文档是否被保护 If ActiveDocument Prote
  • B-S模式API数据传输方案

    随着面向服务技术架构的兴起 越来越多的应用系统开始进行分布式设计和部署 系统由原来的单一的技术架构变成了面向服务的多系统架构 原来在一个系统之间就可以完成的业务流程 现在要通过多系统之间的多次交互实现 那么面向服务的多系统架构之间必然有着大
  • 【openwrt】【编译问题】openwrt编译问题

    undefined reference to pthread once 在某次openwrt编译过程中出现了undefined reference to pthread once错误 具体报错信息如下 openwrt staging dir
  • 备战蓝桥杯day2

    23 01 07 蓝桥杯day2 CH2 杂题 一 填空题 所谓杂题是指没有明确的解题算法 通过思考寻找最简单的解题路径 解题方式包括但不限于手算 编程 excel和简单的python程序 对于一些填空题 手算有时候更加方便快捷 当然手快选
  • 虹膜识别论文5:DeepIrisNet2 2019年 学习心得

    DeepIrisNet2 Learning Deep IrisCodes from Scratch for Segmentation Robust Visible Wavelength and Near Infrared Iris Reco
  • mybatis常用sql汇总

    select sum case when ismm smm type 1 and ismm smm status 0 then ismm smm num else 0 end as monthPurchaseNum sum case whe
  • Dockerfile构建SSH、Systemctl、Nginx、Tomcat、MySQL镜像实验

    目录 一 构建SSH镜像 二 构建Systemctl镜像 三 构建Nginx镜像 四 构建Tomcat镜像 五 构建MySQL镜像 一 构建SSH镜像 1 创建镜像目录方便管理 mkdir opt sshd cd opt sshd 2 创建
  • Vue3注册全局指令

    在src目录下新建directives permission js文件 export default name action mounted el binding vnode console log vnode ctx vonde debu
  • 当我们在讨论设备像素比(device pixel ratio,dpr)的时候我们在讨论什么?

    目录 0 为什么要写这篇文章 1 设备像素比的问题在哪里 1 1 不同的论述导致不同的理解 1 2 设备独立像素与CSS像素 1 3 小结 2 设备像素比 设备物理像素 CSS像素 真的正确吗 2 1 PC端验证 2 2 手机端验证 2 3