《物理像素、CSS像素、多倍图、rem、rpx、em》

背景:
在css中一般使用px作为单位,在pc浏览器中的1个CSS像素往往都是对应着电脑屏幕的1个物理像素,这可能会造成我们以为CSS像素就是设备的物理像素,但实际情况却并非如此!!!
css中的像素只是一个抽象的单位,在不同的设备或不同的环境中,css中的1px所代表的设备物理像素是不同的。在pc端浏览器设计的网页中,无需关注这个,因为在pc端屏幕足够大,一个css像素用一个物理像素来显示,完全可以,pc端默认情况下一个css像素就对应着一个物理像素。
但在移动设备上,必须弄明白这点。在早先的移动设备中,屏幕像素密度都比较低,如iphone3,它的分辨率为320x480,在iphone3上,一个css像素确实是等于一个屏幕物理像素的。后来随着技术的发展,移动设备的屏幕像素密度越来越高,从iphone4开始,苹果公司便推出了所谓的Retina屏(视网膜屏),分辨率提高了一倍,变成640x960,但屏幕尺寸却没变化,这就意味着同样大小的屏幕上,像素却多了一倍,这时,一个css像素是等于两个物理像素的。
1、 物理像素(Device pixels)
又称为设备像素。指设备能控制显示的最小物理单位,即指显示器上一个个的点。从屏幕在工厂生产出的那天起,它上面设备像素点就固定不变了。
比如 iPhone 6 的分辨率为 750 x 1334,单位pt。意思是水平方向含有像素数为750个,垂直方向像素数1334个。屏幕尺寸大小一样的情况下,分辨率越高,显示效果就越精细和细腻 。
pt属于真正的绝对单位,1pt = 1/72(inch),inch及英寸,而1英寸等于2.54厘米。
2、CSS像素(CSS pixels)
又称为独立像素、虚拟像素或逻辑像素,也可以理解为直觉像素。CSS 像素是 Web 编程的概念,指的是 CSS 样式代码中使用的逻辑像素。CSS和JS使用的抽象单位,浏览器内的一切长度都是以CSS像素为单位的.

比如 iPhone 6 的 CSS 像素为 375 x 667,单位是px。但是实际物理像素为 750 x 1334(Retina屏(视网膜屏))。
设备像素比(dpr):devicePixelRatio = 物理像素 / 独立像素。

3.多倍图
为什么需要两倍图/多倍图?
放大会出现模糊:图像是由一个个色彩点也就是色素构成的,假设一个图像开始是1寸,放大到100寸之后,每个色素之间的间隔就扩大了10倍,那么图像自然就模糊了,只能颜色近似选取进行填充。
同一张图展示效果不同:在iPad2或Mini iPad中就是很正常显示的图片;但是,在New iPad中,1个CSS像素点实际上有4个位图像素点,1个分成4个,显然不够分啊,只能颜色近似选取。
对于位图而言:
当图片在标准设备下显示时,1个CSS像素对应的就是一物理像素,会是一个完全保真的显示。因为一个位置像素不能进一步分裂。
当在Retina屏幕下时,1个CSS像素点实际上有4个位图像素点,1个分成4个,显然不够分啊,只能颜色近似选取,于是,图片感觉就是模糊的。
此处简单记录一下位图和矢量图:
位图使用我们称为像素的一格一格的小点来描述图像.计算机屏幕其实就是一张包含大量像素点的网格
矢量图使用线段和曲线描述图像,所以称为矢量,同时图形也包含了色彩和位置信息
区别:
1、位图由像素组成.而矢量图由矢量线组成.
2、矢量图可以无限放大.而且不会失真;而位图而不能,放大会失真,产生模糊。
个人常用解决方法:
二倍图
看一下直接使用图片和使用二倍图呈现的图片的清晰度。上面的是直接使用50px * 50px的图片直接丢到移动端页面的,下面的图片是使用了100px * 100px的图片,进行压缩通过二倍图方式显示的图片。
可以很明显的看出第一张图的边缘有锯齿状,相比之下第二张图则清晰了很多。这就是多倍图的效果。

二倍图的实现
需要一张 100px * 100px的图片显示在移动端
1. 准备一个大图;100px * 100px
2. 手动压缩成大图的一半;设置图片的大小为 50px * 50px
因为IPhone6/7/8的物理像素比是2 , 1px(PC端) = 2个物理像素(移动端的2px),当我们收动压缩为图的一半时,在移动端页面显示的则是原图的大小。如果不压缩的话,就相当于(注意只是相当于)100px*100px的图片放大成200px*200px的图在移动端显示,所以图片会模糊。
看下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>移动端倍图问题</title>
<style>
div {
width: 50px;
height: 50px;
margin-top: 10px;
}
div:nth-child(1) {
background: url(apple50.jpg) no-repeat;
}
div:nth-child(2) {
background: url(apple100.jpg) no-repeat;
background-size: 50px 50px;
}
</style>
</head>
<body>
<div></div>
<div></div>
</body>
</html>
精灵图的二倍图
1. 在PS / Fireworks中,手动把精灵图缩小原来的一半,测量图片的偏移量;
2. 在代码中,手动把精灵图的尺寸(background-size)缩小设置为原来的一半 ----------- 只需要设置宽度,高度设为auto让它自适应。
4. rem
由于 em 存在对父元素继承的问题,当改变字体大小时涉及的继承关系就变得复杂起来。
rem 是相对于根元素 字体尺寸的大小。比如说根元素的font-size是100px,你设置了1.2rem,那么这个元素动态算出来的px数就是120px。不同宽度,设置不同的根元素的font-size,这样就可以适配所有宽度的设备了。
其实我们还可以再除以2,为什么呢,因为我们设计稿量出来的是物理像素,iphone6的dpr是2,我们要把量出来的数除以2,就是实际的px。
5.rpx
微信小程序引入rpx(responsive pixel)这个新的尺寸单位
小程序编译后,rpx会做一次px换算。换算是以375个物理像素为基准,也就是在一个宽度为375物理像素的屏幕下,1rpx = 1px。
举个例子:iPhone6屏幕宽度为375px,共750个物理像素,那么1rpx = 375 / 750 px = 0.5px。
6.em
相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。
由于浏览器的默认字体大小是 16px,所以未经调整默认字体大小的浏览器都符合: 1em = 16px。
em 会继承父级元素的字体大小。由此,只需要改变父元素的字体大小,就可以同步放大或缩小子元素的字体。
但是也因此需要注意几点:
1、body 选择器中声明 Font-size=62.5% (10 ÷ 16 × 100% = 62.5%);
2、将你的原来的 px 数值除以 10,然后换上 em 作为单位;
3、重新计算那些被放大的字体的 em 数值。避免字体大小的重复声明。
浙公网安备 33010602011771号