【问题标题】:How does the browser pick the right image using <img> "sizes" and "srcset" attributes?浏览器如何使用 <img> "sizes" 和 "srcset" 属性选择正确的图像?
【发布时间】:2019-03-15 08:31:18
【问题描述】:

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(srcset)的图片宽度,但那张图片并不总是被选中?为什么?

【问题讨论】:

    标签: css image responsive-design srcset


    【解决方案1】:

    这里是使用Srcset with sizes的详细指南。

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

    sizes 属性与srcset 结合使用可为浏览器提供足够的信息,让浏览器在看到HTML 中的&lt;img&gt; 标记后立即开始下载正确的图像,而无需等待样式表完成下载和解析。

    我们为什么需要尺寸?

    如果您想知道为什么浏览器不知道图像将呈现多大,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. 媒体条件为真时图像元素的宽度。您可以提供绝对长度(px、em)或相对于视口的长度(vw),但不能提供百分比。

    演示 - 带尺寸的 srcset

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

    布局是这样的:

    • 如果视口宽度超过 900 像素,则每张图片的宽度都固定为 225 像素。
    • 最大 900 像素,每张图片占用 33vw,即总视口宽度的 33%。
    • 最多 700 像素,每张图片占用 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 值下会发生什么 -

    【讨论】:

      【解决方案2】:

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

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

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

      • 旧版浏览器不支持srcset
      • 未指定 &lt;meta name="viewport" content="width=device-width"&gt; 以强制设备在加载页面时采用其实际宽度。
      • 浏览器可能会显示缓存的图像,而不是从 srcset 中选择最接近的尺寸匹配(如您在问题中所述)。
      • 当尝试在一个页面上显示多个尺寸的同一图像时,浏览器可能只下载所需的最大图像并在每个实例中使用它(而不是下载多个图像)。
      • 如果您尝试在某种沙盒 iframe 环境(如 jsfiddle)中测试图像选择行为,则很难确定浏览器是否将显示窗格的大小解释为“设备宽度”(我的结果好坏参半在这些类型的环境中使用srcset)。对于 Chrome 和 Firefox 等浏览器,它似乎在 SO sn-p 中表现合理(只要您清除缓存)。请参阅下面的示例 sn-p(最好在您自己的环境中使用),它可以在视觉上明显看出测试时选择了哪个图像。

      <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">

      【讨论】:

      • via.placeholder.com/1000x500 1000w, via.placeholder.com/500x250 500w" sizes="50vw, (min-width: 1000px) 500px" src="via.placeholder.com/300x150" alt="占位符图片" class="banner-image" /> 在 1x 结果屏幕上,这应该只显示 500w 图像,不是吗?
      • @Hakim - 默认的50vw 需要放在sizes 属性的末尾(不是开头),否则,您会希望浏览器选择500w 图像在设备宽度至少为1000px 的设备上(对于较小的设备,因为这是srcset 中最小的图像选项)。
      • 这只是一个例子
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 2020-09-28
      • 2021-10-30
      • 2017-02-06
      • 2019-08-30
      • 2021-10-13
      相关资源
      最近更新 更多