img srcset sizes 的作用

img 标签的 srcset sizes


像素密度:
一开始,img 标签的 srcset 可以用来处理页面在不同像素密度终端设备上对图片的选择性展示。
举个例子,例如下面这个img:

< img src="density-x1.jpg" 
          srcset="density-x1.jpg 1x,
                  density-x2.jpg 2x, 
                  density-x3.jpg 3x" />


解读:
如果当前浏览器不认识 srcset 属性的情况下,浏览器会默认显示 src 中的图片。
如果浏览器认识 srcset 属性,那么浏览器会根据当前屏幕的像素密度来选择相应的图片。
图片的链接和像素密度用空格隔开,如果像素密度为空,那么默认为 1x, 不同的像素密度用逗号分隔开来。

如此以来,在 1x 如果当前设备的像素密度为 1x 则显示 1x 的图片。如果是 2x, 则显示 2x 的图片。
如果你现在面对着一个新的需求, 需要你匹配 1x, 1.2x, 1.75x, 2x....的图片。这个时候我们会想很简单,
我们对不同的像素密度匹配上不同的图片就可以了。于是乎,img 标签就会变得很冗长,而且可能在不同像素
密度下使用的图片是同一张,但是我们不得不为单独的像素密度分配图片,这样情况就会变得糟糕。


如何统一处理不同像素密度 + 屏幕宽度下的尺寸呢?img 标签中 srcset 的宽度描述符 和 size 就是为了解决这一问题。

srcset 宽度描述符
宽度描述符的语法跟密度描述符类似,原本的 x 被 w 所替代,来标识不同的图片源宽度。

< img src="c="cat.jpg" al" alt="cat" 
          srcset="cat-160.jpg 160w, 
                      cat-320.jpg 320w,
                      cat-640.jpg 640w, 
                      cat-1280.jpg 1280w">

但是有了宽度描述符还不够,为什么呢?
因为虽然你给浏览器提供了一系列图片以及他们的真实宽度,也因此可以让浏览器来选择最佳的图片源。
但是浏览器是怎么做到去选择最佳的图片源呢。当浏览器下载图片的时候,他并不知道图片的真实尺寸。

如果我们查看浏览器渲染页面的时间线,我们会发现:
在浏览器下载html 页面不久之后,他将会继续请求css 和 js 资源 img 资源, 但是css,js,img的请求没有先后之分
所以浏览器并不知道页面的布局,所以对图片的尺寸也一无所知,浏览器唯一知道的是视口的尺寸,但是这并不足以
给浏览器选择最佳的图片源。

属性 sizes
sizes 作用就在于告诉浏览器根据屏幕尺寸像素密度的计算值从srcset 中选择最佳的图片源。
需要注意的一点是sizes 只有在srcset 使用宽度描述符的时候才有意义,否则就不需要sizes 属性。

<img src="../static/images/128.png"
     srcset="../static/images/128.png 350w,
             ../static/images/256.png 750w,
             ../static/images/512.png 900w,
             ../static/images/1024.png 1000w"

     sizes="(max- 320px) 100px,
            (max- 450px) 200px,
            (max- 700px) 300px,
            (max- 800px) 400px,
            (max- 900px) 500px,
            1024px">

sizes 的值是由一个逗号分隔开来的列表,列表中的每个值分为两个部分。

(max- 320px) 100px,

第一个部分是媒体情况 (绿色背景部分),他不是媒体查询,但是跟媒体查询类似,用括号包括起来。
第二个部分是长度单位的值 (黄色背景部分),可以是px, vw或者其他单位。

sizes 是如何起作用的呢。
首先浏览器会读取 sizes 然后根据媒体情况来选择,如果匹配到某个值,就根据这个值的长度值单位乘以屏幕像素密度,最终得出来的值再与srcset 中的宽度描述匹配来选择图片。

1. 根据媒体情况 选择 size 中的值。

2. 将值中的长度值 * 屏幕像素密度得到 最终宽度

3. 最终宽度去匹配 srcset 中的宽度描述,得到最终图片