物理像素、逻辑像素、图片的srcset
css 响应式 图片 前端
物理像素(physical pixel)
物理像素又被称为设备像素(dp),他是显示设备中一个最微小的物理部件。一个设备的物理像素是固定不变的。每个像素可以根据操作系统设置自己的颜色和亮度。所谓的一倍屏、二倍屏(Retina)、三倍屏,指的是设备以多少物理像素来显示一个 CSS 像素,也就是说,多倍屏以更多更精细的物理像素点来显示一个 CSS 像素点,在普通屏幕下 1 个 CSS 像素对应 1 个物理像素,而在 Retina 屏幕下,1 个 CSS 像素对应的却是 4 个物理像素。
逻辑像素
CSS 像素/逻辑像素/设备独立像素/设备无关像素(Device Independent Pixels),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css 像素),然后由相关系统转换为物理像素。
设备像素比(Device Pixel Ratio, DPR)
一个设备的物理像素与逻辑像素之比
设备像素比 (dpr)= 物理像素(dp) / 设备独立像素(dip)
在 Retina 屏的 iphone 上,devicePixelRatio 的值为 2,也就是说 1 个 css 像素相当于 2 个物理像素。通常所说的二倍屏(retina)的 dpr 是 2, 三倍屏是 3。
屏幕像素密度 ppi(pixel per inch)
屏幕像素密度(ppi)是指一个设备表面上存在的像素数量,它通常以每英寸有多少像素来计算。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。
屏幕像素密度(ppi) = 对角线分辨率 / 对角线尺寸
DPI(Dots Per Inch,每英寸点数)
是一个量度单位,用于点阵数码影像,指每一英寸长度中,取样、可显示或输出点的数目。 DPI 是打印机、鼠标等设备分辨率的度量单位。比如,800dpi 的话,鼠标每移动一英寸,电脑屏幕上的鼠标指针就会移动 800 个点。dpi 数值越高,鼠标指针移动越快,dpi 越低,鼠标指针移动就越慢。
图片在不同设备像素比的设备上适配
我们希望在不同的设备上显示不同的图片,以确保用户在浏览网站时不会因为网速太慢从而对的移动端用户产生太大的影响。
对于不同分辨率的屏幕,如 4K HD 显示器和 Apple 的 Retina 显示器,在每一个网格中可以显示更多的像素,在这种情况下,为了使图像在这些屏幕上看起来不错,源文件需要大得多是用于常规显示器的图像大小的两倍,三倍甚至四倍。
通常的解决方案
处理高分辨率屏幕的一种方法是简单地提供最大的图像,低分辨率和小尺寸的屏幕可以毫无问题地显示高分辨率的大图像。但是这对于服务器或客户端或低分辨率的用户来说,都是一个非常差的体验。我们希望的是,不管是高分辨率还是低分辨率,都可以根据设备来选择使用不同的图片源,那么,在 web 端又是如何实现它的呢,且让我们继续向下看。
更好的解决方案:提供不同的图像
我们真正想做的是为每个用户都提供最大的可用图片:在高分辨率下,则为他们提供高分辨率的图像,对于手机用户或者低分辨率用户,我们则为他们提供较小的图像。
srcset:提供多图像源
首先,你需要为同一图像创建几个不同大小的版本。通常都希望为每个图像创建至少四个版本:“正常”尺寸的一个,然后再以两倍大小(2x),三倍(3x)和四倍(4x)来创建。创建图像时,将大小规格附加到每个文件会很有帮助:
- image-1x.png
- image-2x.png
- image-3x.png
- image-4x.png
这对浏览器没有任何影响,但会让编码更加易懂。另外,你可以创建更多不同大小(更大,更小)的图片版本,并且 srcset 属性中指定的源文件数量没有限制。
注意:如果您创建的是纯矢量图形,最好将其导出 SVG 文件。因为 SVG 文件可无限扩展,无论分辨率如何,在所有屏幕上的显示效果都很好,且当前所有浏览器版本均支持。
srcset 属性中包括了图像地址信息和设备像素比(可以通过 window.devicePixelRatio 查看,且可以通过 CTRL+MOUSE 齿轮缩放网页来调整 devicePixelRatio 的大小),如下:
<img
src="/static/image.png"
srcset="
/static/image-4x.png 4x,
/static/image-3x.png 3x,
/static/image-2x.png 2x,
/static/image-1x.png 1x
"
/>
sizes:用媒体查询方法来指定图像宽度
通常情况下,我们会通过指定不同的图像宽度(以像素为单位)来告诉浏览器当前设备应该使用哪个图片源。因为它为浏览器提供了更多的有关图像的信息,因此可以更好地决定选择哪个图像。
对于图像宽度,请使用 w 而不是 x。
<img
src="https://cloud4.gogoing.site/files/2020-08-21/bbc63bf5-6f56-4d0a-a996-72fff804725c.png"
sizes="(max-width: 376px) 375px, (max-width: 769px) 768px, 1024px"
srcset="
https://cloud3.gogoing.site/files/2020-08-21/bbc63bf5-6f56-4d0a-a996-72fff804725c.png 375w,
https://cloud2.gogoing.site/files/2020-08-21/69d2679d-eefe-434a-8755-7f8b09166bf3.png 768w,
https://cloud1.gogoing.site/files/2020-08-21/291087d7-beda-402f-9c28-b23e71beb32e.png 1024w
"
/>
- 这里我们使用了三种规格的图片来演示,分别是:375px, 768px 以及 1024px 的图片(左上角标示)。
- sizes 用来表示尺寸临界点,主要跟响应式尺寸有关。其语法为 sizes=“[media query] [value], [media query] [value] … etc”,这里所有的值都是指宽度值,且单位任意可以为 PX, VW, EM 甚至是 CSS3 中的计算值 CALC,这里的 sizes 属性表述为:表示当屏幕不大于 376px 时,图片宽度按照 375px 来计算(计算方式见下一条),当屏幕不大于 769px 时,图片宽度按照 1024px 来计算,其余屏幕按照 1024px 来计算。
- 这里使用的 w 作为宽度描述符,其与 sizes 属性和屏幕密度比(devicePixelRatio)密切相关。比如:
- 在普通的 PC 电脑上,屏幕像素比是 1,sizes 属性计算值为 375px,那么,img 的实际宽度为 375*1=375w,因此,浏览器会加载 375px 这张图片。
- 在 iphone678 这类机型中,屏幕像素比是 2,sizes 属性计算值为 375px,那么,img 的实际宽度为 375*2=750w,此时,375w < 750w < 768w, 因此,浏览器会加载 768px 这张图片。
- iphone plus 和 iphone X 这类机型中,屏幕像素比是 3,sizes 属性计算值为 375px,那么,img 的实际宽度为 375*3=1125w,此时,浏览器会加载 1024px 这张图片。