浏览器如何使用<img>的“sizes”和“srcset”属性选择正确的图像?

5
srcset 属性如何与 sizes 属性一起确定正确的图像呢?以这个图像为例:
<img alt="Demo image"
     sizes="(min-width: 1024px) 512px,
             100vw"
     srcset="img/banner-large.jpg 2048w,
             img/banner-medium.jpg 1400w,
             img/banner-small.jpg 800w">

(我在Chrome中清除了缓存)

我认为最后一个图片 (800w) 会一直选择,因为它符合512px(尺寸)和800w(源集)的要求,但是为什么这个图片并不总是被选中呢?

2个回答

6

这里有一份关于如何使用带有sizes的Srcset的详细指南。

sizes 属性包含一个逗号分隔的列表,列表中的每个项目都描述了图像相对于视口的大小。

使用 sizes 属性与 srcset 为浏览器提供了足够的信息,在看到 HTML 中的 <img> 标签时立即开始下载正确的图像,而不必等待样式表完成下载和解析。

为什么需要 sizes?

如果您想知道为什么浏览器不知道图像将呈现多大,请查看浏览器如何加载网页

语法:

<img src="image.jpg" 
     srcset="small.jpg 300w,
             medium.jpg 600w,
             large.jpg 900w"
     sizes="(max-width: 300px) 100vw, (max-width: 600px) 50vw, (max-width: 900px) 33vw, 900px"
/>

每个用逗号分隔的 sizes 中的项目都有以下内容:
  1. 媒体条件,例如 (max-width: 300px) - 它描述了屏幕可能处于的状态。 (max-width: 300px) 意味着当视口宽度小于或等于 300 CSS 像素时。它类似于媒体查询,但有一些限制。您不能使用 screenprint
  2. 一个空格。
  3. 在媒体条件为真时图像元素的宽度。您可以提供绝对长度(px、em)或相对于视口的长度(vw),但不能使用百分比。

Demo - 使用 sizes 的 srcset

让我们通过实时演示来看看这个 - https://imagekitio.github.io/responsive-images-guide/srcset-sizes.html

布局如下:

  • 如果视口宽度大于900px,则每个图像占用固定的225px宽度。
  • 在900px以下,每个图像占据总视口宽度的33vw即33%的宽度。
  • 在700px以下,每个图像占据总视口宽度的50vw即50%的宽度。
  • 在400px以下,每个图像占据整个视口宽度,即100vw。

单个图像元素的HTML标记如下:

<img src="https://ik.imagekit.io/ikmedia/women-dress-1.jpg" 
     srcset="https://ik.imagekit.io/ikmedia/women-dress-1.jpg?tr=w-225 225w,
             https://ik.imagekit.io/ikmedia/women-dress-1.jpg?tr=w-300 300w,
             https://ik.imagekit.io/ikmedia/women-dress-1.jpg?tr=w-350 350w,
             https://ik.imagekit.io/ikmedia/women-dress-1.jpg?tr=w-640 640w"
     sizes="(max-width: 400px) 100vw, (max-width: 700px) 50vw, (max-width: 900px) 33vw, 225px">

让我们看看不同屏幕尺寸和DPR值下会发生什么-

enter image description here


2
最后一个例子:450像素=> 最接近的候选项:350像素。浏览器不会选择至少等于或优于所需大小的最接近的候选项吗? - Max

1
sizes属性确定适用于当前设备宽度的媒体条件(选择适用的第一个媒体条件)。然后,浏览器检查srcset属性以找到最接近由sizes属性确定的插槽大小的图像。请注意,浏览器会为高分辨率显示器(如Retina)选择更大的图像(通常选择比“普通”分辨率显示器上选择的图像宽度大约两倍的图像)。请参见响应式图片响应式图片:如果只是改变分辨率,请使用srcset,详细了解其工作原理。
因此,在您的情况下,您预计在至少1024px的“普通”分辨率设备上获得banner-small.jpg图像(由于其他srcset图像选项的较大宽度,您还预计在较小宽度的“普通”分辨率设备上获得相同的图像)。
可能导致您未能获得预期结果的一些原因:
  • 老旧的浏览器版本不支持srcset
  • 未指定<meta name="viewport" content="width=device-width">以在加载页面时强制设备采用其真实宽度。
  • 浏览器可能显示缓存的图像,而不是从srcset中选择最接近的尺寸匹配(正如您在问题中所指出的)。
  • 当尝试在页面上显示同一图像的多个尺寸时,浏览器可能仅下载所需的最大图像并在每个实例中使用它(而不是下载多个图像)。
  • 如果您正在尝试在某种沙盒式iframe环境(如jsfiddle)中测试图像选择行为,则很难确定浏览器是否将显示窗格的大小解释为“设备宽度”(我在这些类型的环境中的结果各不相同)。它似乎在像Chrome和Firefox这样的浏览器中的SO片段中表现得相当合理(只要您清除缓存即可)。请参见下面的示例片段(最好在自己的环境中使用),以便在测试时明显地了解哪个图像已被选中。

<img srcset="https://via.placeholder.com/300x150 300w,
             https://via.placeholder.com/600x300 600w"
     sizes="(min-width: 1024px) 600px,
            100vw"
     src="https://via.placeholder.com/300x150"
     alt="placeholder image">


<img srcset="https://via.placeholder.com/1000x500 1000w, https://via.placeholder.com/500x250 500w" sizes="50vw, (min-width: 1000px) 500px" src="https://via.placeholder.com/300x150" alt="占位图像" class="横幅图片" />在1x分辨率屏幕上,这应该只显示500w的图像,不是吗? - Hakim
@Hakim - 默认的50vw需要放在sizes属性的末尾(而不是开头),但除此之外,您可以期望浏览器在设备宽度至少为1000px的设备上选择500w图像(以及较小的设备,因为这是srcset中最小的图像选项)。 - benvc
这只是一个例子。 - Hakim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接