解释图像的`srcset`中的`w`

Explain `w` in `srcset` of image

我了解到 srcset 用于根据设备的 dpi 来确定加载哪个图像。我在 Google Web Fundamentals 上遇到了这个例子,它似乎使用了 w 单位和 vw 单位,恰好是视口宽度的 1%:

<img src="lighthouse-200.jpg" sizes="50vw"
     srcset="lighthouse-100.jpg 100w, lighthouse-200.jpg 200w,
             lighthouse-400.jpg 400w, lighthouse-800.jpg 800w,
             lighthouse-1000.jpg 1000w, lighthouse-1400.jpg 1400w,
             lighthouse-1800.jpg 1800w" alt="a lighthouse">

帮助我了解这是什么计量单位以及我如何使用它?

根据MDNw指的是:

a width descriptor (a positive integer directly followed by w). The width descriptor is divided by the source size given in the sizes attribute to calculate the effective pixel density.

此外,W3 指出:

The user agent will calculate the effective pixel density of each image from the specified w descriptors and the specified rendered size in the sizes attribute. It can then choose any of the given resources depending on the user’s screen’s pixel density, zoom level, and possibly other factors such as the user’s network conditions. If the user’s screen is 320 CSS pixels wide, this is equivalent to specifying wolf-400.jpg 1.25x, wolf-800.jpg 2.5x, wolf-1600.jpg 5x. On the other hand, if the user’s screen is 1200 CSS pixels wide, this is equivalent to specifying wolf-400.jpg 0.33x, wolf-800.jpg 0.67x, wolf-1600.jpg 1.33x. By using the w descriptors and the sizes attribute, the user agent can choose the correct image source to download regardless of how large the user’s device is.

W3 页面上的示例 13 提供了更多详细信息。

w 是图像的固有宽度。这是您右键单击图像并 select 获取 Mac 上的信息或 Windows.

上的属性时获得的数字

为什么需要指定w?因为srcset属性的第一个值只指向link加载图片。它没有说明图像的宽度。浏览器在实际加载图像之前无法判断图像的尺寸。

为什么浏览器需要知道图像的固有宽度?

这是浏览器在加载图像时执行的操作:

  • 看看它的设备宽度
  • 查看 sizes 并找出最适合选择的图像尺寸
  • 查看srcSet中的参考列表,选择大小匹配或大于上面数字的图像。

向MDN借用示例代码:

<img srcset="elva-fairy-480w.jpg 480w,
             elva-fairy-800w.jpg 800w"
     sizes="(max-width: 600px) 480px,
            800px"
     src="elva-fairy-800w.jpg"
     alt="Elva dressed as a fairy">

常见的做法是在图像路径中包含固有图像宽度。然而,没有什么能阻止你这样撒谎:

<img srcset="elva-fairy-480w.jpg 600w,
             elva-fairy-800w.jpg 800w"
     sizes="(max-width: 600px) 480px,
            800px"
     src="elva-fairy-800w.jpg"
     alt="Elva dressed as a fairy">

这意味着如果浏览器的视口宽度为 480px 加载页面,max-width: 600px 条件将为真,并且浏览器有一个 480px 宽的插槽来加载图像。

图像 elva-fairy-480w.jpg 将被加载,因为其固有宽度(600w - 膨胀!)最接近广告位大小。

因此,如果您夸大图像的固有宽度,可能不会有什么坏处。

如果您低估了固有宽度怎么办?

<img srcset="elva-fairy-480w.jpg 280w,
             elva-fairy-800w.jpg 800w"
     sizes="(max-width: 600px) 480px,
            800px"
     src="elva-fairy-800w.jpg"
     alt="Elva dressed as a fairy">

在 480px 的视口宽度上,将加载图像 elva-fairy-800w.jpg,因为据报告 elva-fairy-480w.jpg 为 280w,不符合 sizes 中的说明。

因此,低估图像的固有宽度将导致浏览器加载过大的图像,这违背了响应式 iamges 的目的。

不过,我还没有想过因谎报图像的固有宽度而产生的所有后果。