我可以让 <img> `srcset`/`sizes` 属性考虑到我对 `object-fit: cover` 的使用吗?

Posted

技术标签:

【中文标题】我可以让 <img> `srcset`/`sizes` 属性考虑到我对 `object-fit: cover` 的使用吗?【英文标题】:Can I make the <img> `srcset`/`sizes` attributes take into account my use of `object-fit: cover`? 【发布时间】:2019-08-30 03:13:41 【问题描述】:

在尝试实现全出血背景图像时,我想我发现了结合使用响应式 img srcset/sizes 属性和 CSS 的 object-fit: cover; 的问题。

给定以下简单的测试用例:

<img class="background"
     srcset="//placehold.it/320x180 320w,
             //placehold.it/640x360 640w,
             //placehold.it/960x540 960w,
             //placehold.it/1280x720 1280w,
             //placehold.it/2560x1440 2560w"
     src="//placehold.it/320x180"
     sizes="100vw">
.background 
  position: absolute;
  display: block;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;

(JSFiddle here;孤立的结果页面here)

如果视口的大小类似于纵向智能手机(例如,320×568),浏览器必须垂直放大图像以实现“封面”。这会在水平维度上将图像扩展到视口之外,但是(至少在禁用缓存的 Chrome 中†)因为sizes='100vw'(并且在省略它时,因为100vw 是默认值)浏览器仍然选择源最多适合 320 像素的视口宽度,从而生成像素化图像

我想我理解为什么浏览器会这样做(图像元素本身仍然是 320 像素宽,与图像的可见尺寸无关),但对于我的用例来说,这真是太糟糕了。

我能想到的唯一解决方法是“重载”sizes 属性以强制选择更高分辨率的源。因为我的示例图片是 16:9,我可以使用简单的计算加上 orientation 媒体查询来帮助浏览器了解情况,并使用动态单位告诉它所需的宽度:

<img class="background"
     srcset="//placehold.it/320x180 320w,
             //placehold.it/640x360 640w,
             ..."
     src="//placehold.it/320x180"
     sizes="(orientation: landscape) 100vw,
            calc(100vh / 9 * 16)">

(JSFiddle here;孤立的结果页面here)

这似乎可行,但我不喜欢依赖对 orientation 媒体查询的支持,即使有这种支持,我也不相信这种方法是万无一失的。只是看起来有点脆弱。

我错过了什么吗?这是一个已知的问题?在我今天的研究中,我还没有找到任何关于这种冲突的提及。如果有更强大的方法来解决这个问题,我很想听听。谢谢!

† 如果允许从其缓存中读取,Chrome(和其他)将使用之前加载的任何更高分辨率的源,从而给出不准确的结果。

【问题讨论】:

【参考方案1】:

在这种情况下,必须使用max-aspect-ratio 媒体查询,而不是orientation 媒体查询:

<img
    sizes="(max-aspect-ratio: 16 / 9) calc(100vh * 16 / 9), 100vw"
    srcset="…"
    …
>

【讨论】:

以上是关于我可以让 <img> `srcset`/`sizes` 属性考虑到我对 `object-fit: cover` 的使用吗?的主要内容,如果未能解决你的问题,请参考以下文章

img标签-srcset属性

在此上下文中,元素img不允许作为元素图片的子元素

响应式图片处理

响应式 img srcset 不在横向模式下缩放

srcset的IIS Outbound Rewrite Rule仅重写一次

html 带有SRCSet和大小的IMG标记