结合 HiDPI 监视器了解 srcset 和大小

Understanding srcset and sizes in combination with HiDPI monitors

我进入 CSS 已经有一段时间了,但是图像元素的 srcsetsizes 让我很困惑。这是我认为可行的示例。

<img alt="Background image flowers"
    srcset="img/flowers-480.jpg 480w,
            img/flowers-480@2x.jpg 480w 2x,
            img/flowers-768.jpg 768w,
            img/flowers-768@2x.jpg 768w 2x,
            img/flowers-960.jpg 960w,
            img/flowers-960@2x.jpg 960w 2x,
            img/flowers-1280.jpg 1280w,
            img/flowers-1280@2x.jpg 1280w 2x" 
    sizes="(max-width: 1279px) 100vw,
           (min-width: 1280) 1280px"
    src="img/flowers-960.jpg">

我们的想法是让图像占视口的 100%,直到视口达到 1280 像素或更宽,然后图像将固定大小。但是,为了补偿更高 DPI 设备,我认为建议按照建议添加 DPI 描述符(1.5x、2x 等)here and here

我认为上面的代码会做的是:

但是,当我将其通过验证器时,出现以下错误:

Error: Bad value for attribute srcset on element img: Width for image img/flowers-480@2x.jpg is identical to width for image img/flowers-480.jpg

很明显,我完全忽略了 srcset 和 sizes 的工作原理。我做错了什么?

根据 MDN<img srcset="..."> 定义:

Each string is composed of:

a URL to an image, optionally, whitespace followed by one of:

  • a width descriptor, or 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.
  • a pixel density descriptor, which is a positive floating point number directly followed by 'x'.

您试图同时使用两者,这是非法的。

根据 MDN,“在同一个 srcset 属性中混合宽度描述符和像素密度描述符是不正确的。重复的描述符(例如,同一个 srcset 中的两个源都用'2x'描述)是无效的,也是。

2x 列出了 4 次。那是无效的。

这是来自 MDN 的示例:

示例 4:使用 srcsetsizes 属性

当使用 'w' 描述符时,支持 srcset 的用户代理会忽略 src 属性。当 (max-width: 600px) 媒体条件匹配时,图像将为 200px 宽,否则将为 50vw 宽(视口宽度的 50%)。

<img src="clock-demo-thumb-200.png" 
    alt="Clock" 
    srcset="clock-demo-thumb-200.png 200w,
    clock-demo-thumb-400.png 400w"
    sizes="(max-width: 600px) 200px, 50vw">

对于图像的 HPDI 设置和响应大小的组合,您实际上应该使用 <picture> 以及一些 <source> 和后备 <img> 元素。

详情为in this article

, quoted from developers.google.com 中链接的“艺术指导用例”展示了如何将宽度和像素密度结合起来作为加载和显示图像源的标准:

<picture>
  <source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x">
  <source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x">
  <img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" alt="a head carved out of wood">
</picture>

在至少 800 像素宽的视口中,head.jpg 应显示在单密度显示器上,而 head-2x.jpg 应显示在双倍或更高密度的显示器上。

低于 800 像素但至少 450 像素宽的视口,single-density 显示器应显示 head-small.jpg,而 head-small-2x.jpg 用于双倍密度或更高密度。

<img> 标签内的回退图像定义有另一个 srcset,它定义了一个 double-density 版本 (head-fb-2x.jpg),用于宽度低于 450 像素的视口。

Single-density 不支持源集或图片元素的设备和浏览器将回退显示 head-fb.jpg

在更复杂的情况下,我们还可以添加替代图像格式,以利用 webp 压缩,同时为不支持 webp 的浏览器提供 jpg 版本。

<picture>
  <source media="(min-width: 800px)" srcset="head.webp, head-2x.webp 2x" with="800" height="941">
  <source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x" with="800" height="941">
  <source media="(min-width: 450px)" srcset="head-small.webp, head-small-2x.webp 2x" width="800" height="941">
  <source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x" width="800" height="941">
  <img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" width="400" height="471" alt="a head carved out of wood">
</picture>

这里是一个codepen的复杂例子。

到 2022 年,我认为假设高 DPI 屏幕并利用 srcset:

的断点想法会更容易
<img alt="Background image flowers"
  srcset="img/flowers-480.jpg 480w,
          img/flowers-768.jpg 768w,
          img/flowers-960.jpg 960w,
          img/flowers-1280.jpg 1280w" 
   sizes="(max-width: 1279px) 100vw,
          (min-width: 1280) 1280px"
     src="img/flowers-960.jpg">