1

很长时间以来,我使用图片元素来响应每个视口不同尺寸的图像。它工作得很好,但现在我被迫切换到响应<img>srcset并且sizes我尝试将我的图片元素重写为 IMG 样式。

经过长时间的搜索,我在以下位置找到了很好的文档:

https://www.dofactory.com/html/img/sizes 和更多细节在: https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images

带图片的代码是这样的:

<picture>
    <source media="(max-width: 740px)" src="740.jpg" type="image/jpeg">
    <source media="(max-width: 980px)" src="1280.jpg" type="image/jpeg">
    <source media="(max-width: 1280px)" src="1600.jpg" type="image/jpeg">
    <source media="(max-width: 1480px)" src="1920.jpg" type="image/jpeg">
    <img src="740.jpg" title="..." alt="..." />
</picture>  

我将其重写为这样的响应式 img:

<img src="740.jpg" title="..." alt="..." 
    srcset="
       740.jpg 740w,
       1280.jpg 1280w,
       1600.jpg 1600w,
       1920.jpg 1920w" 
    sizes="
       (max-width: 740px) 740px,
       (max-width: 980px) 1280px,
       (max-width: 1280px) 1600px,
       (max-width: 1480px) 1920px"
/>

这似乎在浏览器的第一次测试中效果很好。但后来我注意到在移动设备上它加载了太大的图像。

原因是某些移动设备的像素密度不同,如 a-complete-guide-for-responsive-images 中所述

您也可以使用 Firefox 的开发工具来模拟它: Firefox 开发工具

我试图通过将代码更改为来解决此问题

<img src="1920.jpg" title="..." alt="..." 
    srcset="
       740.jpg 740w 1x,
       1280.jpg 1280w 1x,
       1600.jpg 1600w 1x,
       1920.jpg 1920w 1x" 
    sizes="
       (max-width: 740px) 740px,
       (max-width: 980px) 1280px,
       (max-width: 1280px) 1600px,
       (max-width: 1480px) 1920px"
/>

不起作用...(它总是为所有视点加载最小的图像)

我从使用 img srcset 处理响应式图像中尝试了没有媒体查询大小的解决方案

不像我需要的那样工作......

所以最大的问题是,如何组合宽度和密度的选择器。

在我的示例中,它应该加载:

  • 740.jpg 用于宽度 0-740
  • 1280.jpg 适用于宽度 740-980
  • 1600.jpg 用于宽度 980-1280
  • 1920.jpg 用于更大的一切

而且我不希望它为像素密度更大的设备加载更大的图像。

我知道 Stackoverflow 中有很多类似的问题,我正在寻找数周的工作解决方案,但似乎没有什么能像预期的那样工作,所以我希望有人能提供解决方案

更新: 我发现,有一个讨论这个问题的 gitlab 问题。

2

(请参阅响应式图像导致性能问题

但目前看来,这个问题还没有最终的解决方案。

如果有人能提供新的想法,我会很高兴。

4

1 回答 1

0

我找到了两种可能的解决方案:

两者都使用最小分辨率媒体查询来定义每个像素密度的单独大小。我用一个比问题更简单的例子来解释它:

理念一

<img src="500.jpg" title="..." alt="..." 
    srcset="
       500.jpg 500w,
       1000.jpg 1000w"
    sizes="
       (min-resolution: 3dppx) 33vw,
       (min-resolution: 2dppx) 50vw,
       (min-resolution: 1dppx) 100vw"
/>

我使用了这些100vh示例,并“还原”了浏览器采用current_with * pixel-density.

此解决方案适用于全屏图像,但您可以使用自定义视口。

想法 2

<img src="500.jpg" title="..." alt="..." 
    srcset="
       500.jpg 500w,
       1000.jpg 1000w"
    sizes="
       (min-resolution: 3dppx) and (max-width: 600px) 1500px,
       (min-resolution: 3dppx) and (max-width: 1200px) 2000px,

       (min-resolution: 2dppx) and (max-width: 600px) 1000px,
       (min-resolution: 2dppx) and (max-width: 1200px) 2000px,

       (min-resolution: 1dppx) and (max-width: 600px) 500px,
       (min-resolution: 1dppx) and (max-width: 1200px) 1000px"
/>

我基于屏幕宽度创建了类似的媒体查询,但添加了“还原”浏览器拍摄图像的大小current_with * pixel-density

此解决方案适用于所有图像,即使它们不是全尺寸。在这里您可以使用自定义视口,但它是相对较多的代码。

两者背后的基本思想:

  • 例如,对于像素密度 2x 和 500px 屏幕宽度,浏览器选择双倍尺寸的 srcset,这是在尺寸媒体查询中定义的,并采用 1000px - 图像
  • 所以我尝试为我想要的大小的两倍(例如 1000 像素)定义新的媒体查询,这需要浏览器获得我想要的 500 像素,当它按像素比进行设备时

在夏天,这意味着:

如果您想恢复浏览器为具有大像素密度的移动设备拍摄更大图像的效果,您必须为每个像素密度的尺寸计算新值。

对于这两种解决方案,您也应该通过 css 定义显示尺寸。

例如,这个简单的 php 代码示例表明:

<?php
  $viewport = [
    // Viewport => Image-Size
    600  => 500,
    1200 => 1000
  ];

  // walk over all pixel-densities
  for($i=3; $i>0; $i--) {
    foreach($viewport as $vp => $w) 
      echo "(min-resolution: {$i}dppx) and (max-width: {$vp}px) "
            .floor($w/$i) . "px,\n";
  }
?>
于 2021-10-19T20:28:45.917 回答