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

时间:2018-10-10 12:16:00

标签: css image responsive-design srcset

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中的缓存)

我认为由于512px(尺寸)和800w(srcset)的图像宽度,将总是选择最后一个图像(800w),但不是总是选择该图像?为什么?

2 个答案:

答案 0 :(得分:2)

此处是使用Srcset with sizes的详细指南。

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

sizes属性与srcset一起使用可为浏览器提供足够的信息,以便在看到HTML中的<img>标签后立即开始下载正确的图像,而无需等待样式表完成下载并解析。

我们为什么需要尺寸?

如果您想知道为什么浏览器不知道图像将呈现多大,请checkout how the browser loads a web page

语法:

<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. 媒体条件为true时图像元素的宽度。您可以提供绝对长度(px,em)或相对于视口的长度(vw),但不能提供百分比。

演示-具有大小的密码集

通过现场演示让我们看到这一点-https://imagekitio.github.io/responsive-images-guide/srcset-sizes.html

布局如下:

  • 如果视口宽度大于900px,则每个图像的宽度均为225px。
  • 最多900像素,每个图像占用33vw,即占总视口宽度的33%。
  • 每个像素最多可容纳700px,即占总视口宽度的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

答案 1 :(得分:0)

sizes属性确定适用于当前设备宽度的媒体条件(选择了第一个适用的媒体条件)。然后,浏览器检查srcset属性以找到与sizes属性确定的插槽尺寸最匹配的图像。请注意,浏览器为诸如Retina的高分辨率显示器选择较大的图像(通常选择接近于其在“正常”分辨率显示器上所选择宽度的两倍的图像)。有关其工作原理的更多详细信息,请参见Responsive imagesResponsive images: If you're just changing resolutions, use srcset

因此,在您的情况下,您希望在设备宽度至少为1024px的“普通”分辨率设备上获得banner-small.jpg图像(并且您也希望在较小宽度的“普通”设备上获得相同的图像“分辨率设备,因为其他srcset个图像选项的宽度较大。

可能无法获得预期结果的一些原因:

  • 旧版浏览器不支持srcset
  • 未指定<meta name="viewport" content="width=device-width">来强制设备在加载页面时采用其实际宽度。
  • 浏览器可能会显示缓存的图像,而不是从srcset中选择最接近的尺寸匹配项(如您在问题中所述)。
  • 当尝试在页面上显示同一尺寸的多个图像时,浏览器可能只会下载所需的最大图像,并在每个实例中使用它(而不是下载多个图像)。
  • 如果您尝试在某种沙盒iframe环境(例如jsfiddle)中测试图像选择行为,则很难确保浏览器将显示窗格的大小解释为“设备宽度”(我的结果有误)在这些类型的环境中使用srcset)。对于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">