skip to Main Content

I was checking Core Vitals on PageSpeed insight and noticed its flagging Image elements do not have explicit width and height and suggesting Set an explicit width and height on image elements to reduce layout shifts and improve CLS.

I am not sure what it exactly means and what i can do properly to resolve this issue, specific to my case

<img src="someimage.jpg" width="100%" height="100%" alt="something" class="img-responsive">

My page is responsive and i am using bootstrap v3.x for this webpage as its is old page. since page is responsive and i am using class="img-responsive" which automatically resizes image with, but this impacts core vital such as CLS.

Since layout is responsive what is the best approach to define use image to avoid CLS issue.

I have noticed most of the CLS reported by Page Speed Insigh is for owl Carousal

Below is the copy of code which generate CLS issue for images

<div class="container">
  <div class="row">
    <div class="col-md-12 col-lg-12 lc-hp-col">
      <div class="owl-carousel owl-theme" data-items="1" data-items-desktop="1" data-items-tablet="[991,1]" data-items-mobile="[767,1]" data-pagination-speed="200" data-auto-play="true" data-stop-on-hover="true">
        <div class="item">
          <img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+1">
        </div>
        <div class="item">
          <img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+2">
        </div>
        <div class="item">
          <img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+3">
        </div>
        <div class="item">
          <img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+4">
        </div>
        <div class="item">
          <img alt="ALT" class="img-responsive" src="https://dummyimage.com/992x588/000/3431af&text=IMAGE+5">
        </div>
      </div>
    </div>
  </div>
</div>

CodePen link

Some article have suggested to use scrset for responsive images but this is not practical as we have to then upload multiple versions of same image.

<img
  width="1000"
  height="1000"
  src="puppy-1000.jpg"
  srcset="puppy-1000.jpg 1000w, puppy-2000.jpg 2000w, puppy-3000.jpg 3000w"
  alt="Puppy with balloons"
/>

5

Answers


  1. Answer

    The width and height we are talking about, are intended to be a fixed number to avoid the warning.

    That’s needed to reserve the (explicit) required space for the image while it’s loading. If you give it a percentage, the browser cannot know the size it will need, so it will be changing, and cause the page layout to shift (that’s what we try to avoid).

    Edit

    I’m not sure about what you mean with "it becomes even harder". No one said it’s easy, as you have a complex problem.

    You are trying to:

    • Serve a responsive carousel.
    • A carousel with responsive images.
    • Avoid warnings from Web Vitals about Layout Shifts.

    Complex solutions for complex problems, that’s what it is.

    Login or Signup to reply.
  2. NOTE: The sizes of your images are fix as of Bootstrap mechanic!

    If you have a nearer look to your page your images are responsive but not fluent. That means the size does change in predfined steps when the vieport changes the width. Inbetween this steps the sizes for the images are allways the same even if the sizes are set in percentage. That’s the mechanic of Bootstrap.

    So, – your are able to set fixed values to the sizes of your images without changing the layout!!!

    You will find the original steps Bootstrap uses (if not changed for the project) here:
    https://getbootstrap.com/docs/3.4/css/#grid-media-queries

    As you see Bootstrap standard is: if viewport width becomes more than 769px the size changes, same as on 992px and on 1200px.

    Taken from the codepen example the sizes of your images are:

    // Up from Vieport width:  
    768px = Image: 720x426px   
    992px = Image: 940x557px   
    1200px = Image: 992x588px  
    

    (Note: below viewport widht 768pxcodepen does not work. Have a look for the size(s) on original page.)

    Knowing that you are able to advice fixed sizes to the images by media queries. You may do this using sass with the original tools of Bootstrap (see link above). Or do something like this:

    /* below 768px take values from original page */
    
    @media (min-width: 768px { 
       .owl-carousel img {
          width: 720px !important;
          height: 426px !important; 
    }
    @media (min-width: 992px { 
       .owl-carousel img {
          width: 940px !important;
          height: 552px !important; 
    }
    @media (min-width: 1200px { 
       .owl-carousel img {
          width: 992px !important;
          height: 588px !important; 
    }
    
    

    NOTE: I am not quite sure if that css overwrites the Bootstrap markup. So maybe you have to give it an higher specificity i.e. by using div.owl-carousel div imgor something similar. And if height is not correct please readout all sizes from original page. Sometimes you will need to be more exact i.e. with height: 588.xxxx px.

    Login or Signup to reply.
  3. When you use img src tag so you need to add width and height whatever actual image width and height attribute with img tag for an Example like this:

    Dummy Image

    So it is not Create CLI in google page insights.

    Login or Signup to reply.
  4. There is no real solution to this issue other than the srcset solution that you mentioned. The layout shift issue will likely be flagged unless you specify image dimensions.

    I agree that the integration of multiple image sizes is difficult & cumbersome & perhaps not always justified. Even if you integrate the multiple sizes of images you can still have a layout shift if the images are set to scale responsively to ANY size rather than just a set of options.

    The CLS is less likely to be flagged by Google (or to bother any users) if your images begin to load very quickly so that the image sizes are known before the layout has a chance to fully render (& thus shift). Defer anything you can to bring the images towards the front of the line.

    This may be questionable but I implemented a tiny generated png to get the image data loaded very quickly like this:

    <img class="img_scale"
        src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" 
        data-src="/img/img.jpg"
    />
    

    You may also be able to use csscalc to estimate the percentage, pixel value or em value of a container for the image in order to greatly reduce the amount of shift. You probably can’t eliminate it without using static sizes but you can cut it way down.

    Login or Signup to reply.
  5. You can work around this problem by

    • Setting explicit <img width height> – for height value use your best guess what the most image heights will be

    • Later override the HTML element height attribute with the following CSS:

       .my-img {
            height: auto;
        }
    

    However note that this causes cumulative layout shift, CLS, event after the image is loaded, so you are essentially shifting the problem around. The CLS issue can be worked around by making sure the container element hosting the image has min-height set.

    Here is the full source code for an example Svelte component where I worked around this problem.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search