处理不同尺寸的延迟加载图片的纵横比,避免内容跳转
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 你在处理一组有限的纵横比吗?如果是这样,那么您可以为每个纵横比使用不同的类。如果没有,那么预先设置img
、height
和width
可以防止内容重排。
【讨论】:
图片由用户上传。此图像是无尺寸的。这意味着用户可以上传任何尺寸的图像,例如:400x100 和/或 1080x720。在渲染这些图像之前,我会向图像优化服务发送请求,以根据用户设备的屏幕宽度获取适当的图像尺寸。 这意味着在图像标签而不是 CSS 中设置 H/W。所以<img height="300" width="400" />
如果您等待 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>
【讨论】:
以上是关于处理不同尺寸的延迟加载图片的纵横比,避免内容跳转的主要内容,如果未能解决你的问题,请参考以下文章
使用 flexbox 并保持 1:1 的纵横比,即使内容大小不同