首页 > 解决方案 > 即使设置 CSS min-height,Lighthouse 也会报告高 CLS

问题描述

Lighthouse 中的累积布局偏移报告的数字很高:0.546

分析跟踪我注意到图像块最初没有占用所需的空间并将下面的内容向下推。见图片: 在此处输入图像描述

我对此感到惊讶,因为图像元素的容器 div 具有最小高度设置:

CSS

div[itemprop="image"] {
    display: inline-block;
    float: left;
    margin-right: 10px;
    min-height: 400px;
}

#prodimage {
    width: 100%;
    max-width: 400px;
    border: 1px solid #FFF;
}

HTML

<div itemprop="image" itemscope="" itemtype="http://schema.org/ImageObject">                
    <a href="#"><span itemprop="url" content="https://www.example./com/images/10055041.png"></span>
        <picture><source type="image/webp" data-srcset="/images/10055041.webp" srcset="/images/10055041.webp">
            <img id="prodimage" data-src="/images/10055041.png" src="/images/10055041.png">
        </picture>
    </a>
</div>

标签: csslighthousecumulative-layout-shift

解决方案


你需要在你的内联 CSS 中给你的图片一个高度和宽度

当您放置一个<img/>元素时,浏览器在联系服务器之前不知道它有多大。

当您内联 CSS 时,浏览器将纯粹从初始请求(您的页面 HTML 和内联样式)呈现页面。

因此,它会尝试计算布局,通过内联 CSS 查找图像的大小信息,找不到任何宽度信息,因此不知道为图像分配多少水平空间。

然后浏览器从您的服务器请求图像,找出大小并知道分配400px400px.

这是你的布局发生变化的地方,它从一个0px宽×400px高的空间变成了一个400px宽×高的空间400px(加上 1px 边框)。

通过将 a 分配给图像,您已经完成了一半min-height,但您还需要min-width为图像定义 a。

因此,您的 CSS 应该是:

div[itemprop="image"] {
    display: inline-block;
    float: left;
    margin-right: 10px;
    min-height: 400px;
    min-width: 400px;
}

处理图像的更好方法

作为一个额外的想法,一个更好的选择而不是为图像设置定义的大小是使用响应式布局。

您在那里所做的是将图像添加到<div>宽度定义为百分比的等。

然后你把你的<img/>里面那个<div>with width: 100%

这样就解决了浏览器计算宽度的问题。

要计算高度,然后添加width="400"height="400"您的<img/>.

在大多数浏览器中,他们然后使用它来计算图像aspect-ratio

这让浏览器通过将宽度乘以纵横比来分配足够的垂直高度。

例子

在下面的示例中,您会注意到我将<img/>宽度设置为 40,高度设置为 40。

这是为了表明,只要它们是正确的纵横比,您在此处设置什么并不重要。(所以你可以设置一个 16:9 的图像width="16"height="9"即使图像是 800 x 450)。

浏览器遵循以下流程:

  • 屏幕上的 div 有多大(在 660 像素宽的屏幕上是 200 像素。)。
  • 图像的宽度(100% * 200 像素 = 200 像素)。
  • 什么是纵横比?(宽度/高度 => 40 / 40 = 1:1)。
  • 将计算出的宽度乘以高度(200 像素 * 1)。

因此,浏览器会在开始请求之前为图像分配 200 像素 x 200 像素的空间,因此您不会获得布局变化。

<style>
   .holder{
       width: 33%;
       background-color: #333;
   }
   img{
       width: 100%;
       height: auto;
   }
</style>

<div class="holder">
  <img src="https://placehold.it/400x400" width="40" height="40" />
</div>
    
    <p>text that will not move</p>


推荐阅读