Skip to content

物理像素与逻辑像素

像素

物理像素

屏幕由N个小方块构成,每个小方块都只能显示一个颜色,而一个小方块,就是一个物理像素。

在不同的设备上,这个小格子的大小是不同的,所以物理像素并不是一个固定大小的单位,只代表一个显示器上的小格子

逻辑像素px

物理像素是硬件开发的单位,大小由硬件厂商设定

逻辑像素,是软件开发的单位,软件相关的工作人员通过逻辑像素来表达软件相关的尺寸

前端css、浏览器显示给开发者的尺寸、UI设计师给出的UI稿。其尺寸都是逻辑像素

像素比DPR

像素比=物理像素/逻辑像素

像素比就是物理像素与逻辑像素的比值,即当前设备将通过几个物理像素点来绘制一个逻辑像素点

图像的尺寸=CSS尺寸*DPR

分辨率

物理分辨率

物理像素点的总数即为物理分辨率

逻辑分辨率

逻辑像素点的总数即为逻辑分辨率

响应式图像

对于<img>标签用于插入网页图像,所有情况默认插入的都是同一张图像

html
<img src="foo.jpg">

这种方法的弊端:

1、体积。桌面端显示的是大尺寸的图像,文件体积较大。手机屏幕较小,只需要小尺寸图像,可以节省带宽,加速网页渲染。

2、像素密度。桌面显示器一般是单倍像素密度,而手机的显示屏往往是多倍像素密度,即多个像素合成为一个像素,称为Retina屏幕。

3、视觉风格。桌面显示器的面积较大,图像可以容纳更多细节。手机屏幕较小,许多细节是看不清的,需要突出重点。

像素密度选择:srcset属性

为了解决上述问题,<img>标签引入了srcset属性

srcset属性用来指定多张图像,适应不同像素密度的屏幕。它的值是一个逗号分隔的字符串,每个部分都是一张图像的 URL,后面接一个空格,然后是像素密度的描述符。

html
<img srcset="foo-320w.jpg,
             foo-480w.jpg 1.5x,
             foo-640w.jpg 2x"
     src="foo-640w.jpg">

图像 URL 后面的像素密度描述符,格式是像素密度倍数 + 字母x1x表示单倍像素密度,可以省略。浏览器根据当前设备的像素密度,选择需要加载的图像。

图像大小选择:srcset属性+sizes属性

像素密度的适配,只适合显示区域一样大小的图像如果希望不同尺寸的屏幕,显示不同大小的图像,srcset属性就不够用了,必须搭配sizes属性

1、srcset属性列出所有可用的图像

html
<img srcset="foo-160.jpg 160w,
             foo-320.jpg 320w,
             foo-640.jpg 640w,
             foo-1280.jpg 1280w"
     src="foo-1280.jpg">

每张图像的 URL 后面是一个空格,再加上宽度描述符

宽度描述符就是图像原始的宽度,加上字符w。上例的四种图片的原始宽度分别为160像素、320像素、640像素和1280像素。

2、sizes属性列出不同设备的图像显示宽度

sizes属性的值是一个逗号分隔的字符串,除了最后一部分,前面每个部分都是一个放在括号里面的媒体查询表达式,后面是一个空格,再加上图像的显示宽度。

html
<img srcset="foo-160.jpg 160w,
             foo-320.jpg 320w,
             foo-640.jpg 640w,
             foo-1280.jpg 1280w"
     sizes="(max-width: 440px) 100vw,
            (max-width: 900px) 33vw,
            254px"
     src="foo-1280.jpg">

上面代码中,sizes属性给出了三种屏幕条件,以及对应的图像显示宽度。宽度不超过440像素的设备,图像显示宽度为100%;宽度441像素到900像素的设备,图像显示宽度为33%;宽度900像素以上的设备,图像显示宽度为254px。

3、浏览器根据当前设备的宽度,从sizes属性获得图像的显示宽度,然后从srcset属性找出最接近该宽度的图像,进行加载。

注意,sizes属性必须与srcset属性搭配使用。单独使用sizes属性是无效的。

<picture>标签、<source>标签

如果要同时适配不同像素密度、不同大小的屏幕,就要用到<picture>标签

<picture>标签是一个容器标签,内部使用<source><img>,指定不同情况下加载的图像。

html
<picture>
  <source media="(max-width: 500px)" srcset="cat-vertical.jpg">
  <source media="(min-width: 501px)" srcset="cat-horizontal.jpg">
  <img src="cat.jpg" alt="cat">
</picture>

<source>标签的media属性给出媒体查询表达式,srcset属性就是<img>标签的srcset属性,给出加载的图像文件。sizes属性其实这里也可以用,但由于有了media属性,就没有必要了。

浏览器按照<source>标签出现的顺序,依次判断当前设备是否满足media属性的媒体查询表达式,如果满足就加载srcset属性指定的图片文件,并且不再执行后面的<source>标签和<img>标签。

<img>标签是默认情况下加载的图像,用来满足上面所有<source>都不匹配的情况。

<source>标签的type属性

<picture>标签还可以用来选择不同格式的图像。比如,如果当前浏览器支持 Webp 格式,就加载这种格式的图像,否则加载 PNG 图像。

html
<picture>
  <source type="image/svg+xml" srcset="logo.xml">
  <source type="image/webp" srcset="logo.webp"> 
  <img src="logo.png" alt="ACME Corp">
</picture>

浏览器按照<source>标签出现的顺序,依次检查是否支持type属性指定的图像格式,如果支持就加载图像,并且不再检查后面的<source>标签了。

参考

https://juejin.cn/post/7190723647030427708

https://github.com/jawil/blog/issues/21

https://www.ruanyifeng.com/blog/2019/06/responsive-images.html

喜欢这个项目?

如果这些内容对您有帮助,请考虑给项目一个⭐