处理不同尺寸的延迟加载图片的纵横比,避免内容跳转

Posted

技术标签:

【中文标题】处理不同尺寸的延迟加载图片的纵横比,避免内容跳转【英文标题】:Handling aspect ratio of lazy loading images with different dimensions to avoid content jump 【发布时间】:2019-12-18 20:15:26 【问题描述】:

借助 padding-top: calc(height / widht * 100%); 我可以处理延迟加载图像以避免内容跳转。

但这个解决方案只有在所有图像都在同一维度时才能完美运行。

渲染不同维度图片时如何处理内容跳转?

仅供参考:对于延迟加载图像,我使用lazysizes

.wrapper 
  position: relative;
  height: 0;
  padding-top: calc(100 / 411 * 100%);


.wrapper_img 
  position: absolute;
  top: 0;
  left: 0;
  max-width: 100%;
  height: auto;
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <div>
    <p>Test 001</p>

    <div>
      <div class="wrapper">
        <img class="wrapper_img" src="https://placehold.it/411x100" />
      </div>
    </div>

    Test 002

    <div>
      <div class="wrapper">
        <img class="wrapper_img" src="https://placehold.it/150x100" />
      </div>
    </div>

    Test 003

    <div>
      <div class="wrapper">
        <img class="wrapper_img" src="https://placehold.it/411x600" />
      </div>
    </div>

    Test 004

  </div>
</body>

</html>

Here 是 JSBin 的链接。

【问题讨论】:

然后为每张图片定义一个不同的类 你能澄清一下content jump是什么意思吗? @Hitmands 我的意思是内容重排css-tricks.com/content-jumping-avoidvoorhoede.nl/en/blog/say-no-to-image-reflow 标准定义您需要在图像上具有宽度/高度属性 【参考方案1】:

@sravis 你在处理一组有限的纵横比吗?如果是这样,那么您可以为每个纵横比使用不同的类。如果没有,那么预先设置imgheightwidth 可以防止内容重排。

【讨论】:

图片由用户上传。此图像是无尺寸的。这意味着用户可以上传任何尺寸的图像,例如:400x100 和/或 1080x720。在渲染这些图像之前,我会向图像优化服务发送请求,以根据用户设备的屏幕宽度获取适当的图像尺寸。 这意味着在图像标签而不是 CSS 中设置 H/W。所以&lt;img height="300" width="400" /&gt; 如果您等待 CSS,您可能会导致重绘。您还可以考虑使用native lazy load 解决方案。【参考方案2】:

由于您没有一组纵横比,因此在渲染 html 时将需要图像大小(或纵横比)。 指定图像宽度/高度属性很好,但不能解决您的问题。

你能做什么

一个想法是通过使用 padding-top 的实现以 内联样式 为包装 div 提供纵横比。

另一个使用内联样式和自定义 css 变量的想法是broadly supported。看一下sn-p。这是一个具有固定包装宽度和边框并放大图像的示例。

无论你决定使用什么

注意损坏的图片,这可能会破坏您的宽高比。 太小而无法填满整个包装的图像会在布局中看起来有点丢失。要么使用 object-fit 和 object-postion 来解决这个问题 - 或者像在 sn-p 中那样省略 max-widh 来扩大它们。

/* css for wrapper only for demonstration purposes and not really needed */

.wrapper 
  width: 300px; /* just to limit the size */
  border: 1px solid black;
  box-sizing: border-box;



/* tricky stuff starts here */

[style*="--aspect-ratio"] 
  position: relative;


[style*="--aspect-ratio"]::before 
  content: "";
  display: block;
  padding-bottom: calc(100% / (var(--aspect-ratio)));


[style*="--aspect-ratio"] > img 
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <div>
    <p>Test 001</p>

    <div>
      <div class="wrapper" style="--aspect-ratio:411/100">
        <img class="wrapper_img" src="https://placehold.it/411x100" />
      </div>
    </div>

    Test 002 (broken by intention)

    <div>
      <div class="wrapper" style="--aspect-ratio:150/100">
        <img class="wrapper_img" src="https://broken-placehold.it/150x100" />
      </div>
    </div>

    Test 003

    <div>
      <div class="wrapper" style="--aspect-ratio:411/600">
        <img class="wrapper_img" src="https://placehold.it/411x600" />
      </div>
    </div>


Test 004

    <div>
      <div class="wrapper" style="--aspect-ratio:150/100">
        <img class="wrapper_img" src="https://placehold.it/150x100" />
      </div>
    </div>
  </div>
</body>

</html>

【讨论】:

以上是关于处理不同尺寸的延迟加载图片的纵横比,避免内容跳转的主要内容,如果未能解决你的问题,请参考以下文章

WPF的窗口中的所有内容随窗口大小变化而同步变化

使用 flexbox 并保持 1:1 的纵横比,即使内容大小不同

在按钮单击时设置 JCrop 的纵横比?

如何使用“包含”选项调整图像的大小,但保留原始尺寸的纵横比?

调整图像大小并裁剪为新的纵横比

Android:如何计算图像的纵横比?