物理像素?逻辑像素?设备像素比(DPR)?这些是什么???
去年面试的时候遇到的一个面试题,当时回答的不是非常完整,今天想起来了整理一下。
物理像素
物理像素是屏幕上最小的发光单元,也被称为设备像素(device pixel, dp)。每一个物理像素都是由红、绿、蓝三种颜色的小灯组成,通过调整这三种颜色的亮度,可以显示出各种不同的色彩。例如,iPhone 12 mini 的分辨率为1080×2340像素,这意味着它的屏幕上水平方向有1080个物理像素点,垂直方向有2340个物理像素点。每个物理像素的数量是固定的,一旦设备生产出来就不会改变,这是决定显示效果的基础。
逻辑像素
与物理像素相对应的概念是“逻辑像素”,有时也被称作设备独立像素(device independent pixels, dips)。逻辑像素是一个抽象的概念,它用于描述屏幕上物体的视觉尺寸。换句话说,无论你的屏幕有多大或者分辨率有多高,只要逻辑像素相同,那么物体看起来或打印出来的大小就会一样。比如,我们在CSS中定义一个宽度为300px的元素,这里的“300px”实际上是指逻辑像素,而不是直接对应于物理像素,也就是说,实际上渲染这个300px的元素用到了多少的物理像素,是不一定的,通常可以认为,如果1px逻辑像素对应的物理像素越多,展示效果就越清晰。逻辑像素的存在使得我们可以编写跨设备兼容的代码,确保我们的应用在不同设备上具有相似的用户体验。
什么是DPR?
DPR是指设备的物理像素数量与CSS像素数量之间的比率。换句话说,它是用来衡量一个逻辑像素(通常指的是CSS中的1px)对应多少个物理像素。例如,在一台DPR为2的设备上,每个逻辑像素由4个物理像素组成(2x2),这意味着屏幕上的图像和文本会更加清晰,因为它们使用了更多的物理像素来呈现。至于为何要变成2x2的四个像素点,简单点来说,缩放也需要保持之前的形状,像素点一般是方形的,所以缩放之后的像素点当然也是一个方形的阵列。为了维持图像元素的形状和比例,并充分利用更高的分辨率提供的细节增强效果,逻辑像素与物理像素之间的转换遵循相同的比例原则,即在水平和垂直方向上均采用相同的放大系数。
下图是一个简单的示例,展示DPR为2的设备的缩放情况。可以非常直观的感受到,如果离远了看,4个物理像素表示1个逻辑像素的方式会具有更加清晰的细节。
CSS像素 vs 物理像素
- CSS像素:也称为逻辑像素或独立设备像素,是在网页设计中使用的抽象单位。它们是相对的,并不直接对应于屏幕上的实际物理像素。
- 物理像素:是显示器能够控制显示的最小单元,这些像素的数量是固定的,一旦设备出厂就不会改变。
当DPR等于1时,意味着每一个CSS像素正好对应一个物理像素;而当DPR大于1时,则表示一个CSS像素对应多个物理像素。例如,一个设备的DPR为2,这使得即使屏幕尺寸没有变化,但分辨率却提高了一倍,从而提供了更精细的图像质量。
如何处理DPR?
为了确保网站在各种不同的DPR值下都能有良好的表现,我们可以采取以下几种策略:
- 媒体查询:利用CSS媒体查询可以根据DPR加载不同的样式表或规则集,以适应不同分辨率的设备。例如,针对高DPR设备提供更高分辨率的背景图片。
/* 针对低DPR设备 */
body {
font-size: 16px;
background-image: url('background-low-dpr.jpg');
}
/* 针对高DPR设备 */
@media only screen and (min-device-pixel-ratio: 2) {
body {
font-size: 18px;
background-image: url('background-high-dpr.jpg');
}
}
- JavaScript动态调整:通过JavaScript检测用户的DPR值,并据此动态加载资源或调整页面元素的大小。例如,根据DPR值加载不同分辨率的图片以优化视觉效果和加载速度。
const loadImages = () => {
const images = document.querySelectorAll('img[data-src]');
images.forEach(img => {
const src = img.getAttribute('data-src');
const dpr = window.devicePixelRatio;
img.src = dpr > 1 ? `${src}-high.jpg` : `${src}-low.jpg`;
});
};
window.addEventListener('load', loadImages);
window.addEventListener('resize', loadImages);
- 响应式图片:采用
srcset
属性或者<picture>
标签来为不同的DPR值提供相应的图片版本,保证在高分辨率屏幕上也能呈现出高质量的图像。
<img
src="image-low-dpr.jpg"
srcset="image-medium-dpr.jpg 2x, image-high-dpr.jpg 3x"
alt="Responsive Image Example"
>