即使设置 CSS 最小高度,Lighthouse 也会报告高 CLS

Lighthouse reports high CLS high even when setting CSS min-height

Lighthouse 中的 Cumulative Layout Shift 报告了一个很高的数字:0.546

分析跟踪我注意到图像块最初没有占用所需的 space 并将内容向下推。见图片:

我对此感到惊讶,因为图像元素的容器 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>

您需要在内联 CSS.

中为图像指定高度 和宽度

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

由于您已内联 CSS,浏览器将完全根据初始请求呈现页面(您的页面 HTML 和内联样式)。

正因为如此,它会尝试制定布局,通过内联 CSS 查看图像的尺寸信息,但找不到任何宽度信息,因此不知道水平方向有多少 space 为图像分配。

然后浏览器向你的服务器请求图像,找出大小并知道分配400px 400px

这是您的布局转换发生的地方,它从 0px400px 高 space 变为 400px400px 高(加上 1px 边框)space.

为图像分配 min-height 已完成一半,但您还需要为图像定义 min-width

因此您的 CSS 应该是:

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

处理图像的更好方法

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

你所做的是将图像添加到 <div> 等,其宽度定义为百分比。

然后将 <img/> 放入 <div>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)。

因此,浏览器甚至在开始请求之前就会为图像分配 200px x 200px space,这样您就不会发生布局偏移。

<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>