In the previous post, we discussed the basics of the Core Web Vitals.

This is the second post in our series on Core Web Vitals which discusses the major causes of Cumulative Layout Shifts and their fixes.

Cumulative Layout Shift (CLS) is the third metric in the Core Web Vitals which measures the web page’s visual instability.

Visual instability of a webpage is due to layout shifts that happen unexpectedly. 

These unexpected layout shifts cause poor user experience and can be annoying & distracting.

This post discusses the causes of unexpected Layout Shifts and steps to fix them.

Major causes of Layout Shifts

CLS mainly occurs due to the change in the DOM element’s position or dimensions.

The most common causes for CLS are, 

  • Images without width and height attributes
  • Ads, iframes, and embeds with no reserved space 
  • Web Fonts causing FOIT or FOUT
  • Dynamically inserted elements above the existing elements  

Let’s dive deeper to understand each one of these causes.

Images without width and height attributes 

The problem

Consider the below situation. An image without width and height specified is requested from the server. 

A screencast showing Image loaded without width and height causing layout shift

Before downloading the image the browser doesn’t know the amount of space that it should allocate.

Once the image is loaded, the browser allocates the required space thus shifting the elements below it. This causes layout jank.

The solution

Following is the solution for responsive images with minimum layout shift.

<style>
img {
  width: 100%;
  height: auto;
}
</style>
 <img 
    width=”800”
    height=”800”
    src=”demo-image-800.jpg”
    srcset=”demo-image-480.jpg 480w, 
                 demo-image-800.jpg 800w”     
    sizes=”(max-width: 600px) 480px, 100%”
     alt=”This is Demo Image”
/>

Ads, iframes, and embeds with no reserved space

The problem

As with the images, advertisements can contribute to a high CLS score. Advertisements in most cases load asynchronously. If sufficient space is not reserved beforehand they can cause CLS.

A screencast showing advertisements causing layout shift

For optimal performance publishers often support dynamic ad sizes like fluid & multi-size ad slots which gives better CTR. These ads may expand or collapse, depending on the settings, thus triggering layout shift.

The solution 

To fix CLS issues created by ads, reserve space statically beforehand. Although, due to the variety of ad sizes available, a one-size-fits-all space allocation is difficult. Instead, make adjustments to size allocation until its layout shifts free. 

The size to be allocated can be determined by historical data reports from the publisher. 

For e.g, there are two ads of sizes 300×240 & 320×60 which are delivered. Allocating a height of 240 px can avoid layout shift. 

The bare minimum code for a multi-size ad slot could be,

<div 
    id="publisher-ad-slot" 
    style="min-width: 300px; min-height: 250px;">
</div>

Using media queries different devices should be targeted.

For fluid ad slots, it’s recommended to reserve a slot below the fold as they would definitely resize and cause layouts shifts.

Dynamically inserting elements above the existing elements 

The problem 

As with images and ads, dynamic content is also responsible for CLS. The new content is dynamically added on top of the existing content. 

 Following are some examples of dynamically injected content, 

  • Newsletter signups
  • Register for a webinar or conference
  • Campaigns and special offers
  • Install mobile apps 
  • Download whitepaper or ebook

 The solution 

The straightforward solution is to reserve space for these content boxes instead of dynamically injecting them. It pre-informs the browser to allocate space avoiding layout shifts.

Custom web fonts causing FOUT or FOIT

The problem

Another common cause of Cumulative Layout Shift is custom fonts. As compared to the other causes, custom fonts have a smaller impact but still, the layout shift is visible.

Custom fonts have to be downloaded and rendered. Till the fonts are loaded two problems can occur depending on the font-display CSS property set.

FOUT (Flash of Unstyled Text) occurs when the custom font is downloaded and is swapped with the fallback font. Until the font is being downloaded the fallback font is displayed.

A screencast showing Flash of Unstyled Text (FOUT)

FOIT (Flash of Invisible Text) is when the browser doesn’t display any font, not even fallback font. It shows invisible text till the custom fonts are loaded. 

A screencast showing Flash of Invisible Text (FOIT)

In both cases any font that renders smaller or larger than its fallback causes layout shift.

The solution

As of now to avoid CLS caused by fonts, there is only one solution.

The idea is to use <link rel=”preload”> along with CSS property font-display: optional.

This will load fonts without layout jank when rendering custom fonts.

Here is the code,

 <link 
     rel="preload" 
     href="/assets/Pacifico-Bold.woff2" 
     crossorigin as="font" 
     type="font/woff2" >

This codelab explains in detail how the above code works.

Closing thoughts 

Minimizing CLS score should be on high priority for website owners since layout shift leads to a poor user experience. 

The common solution to fix Layout shifts is to reserve space. Reaching a CLS score of 0 should be an ideal target.

Here is a screenshot of Gtmetrix for a web page that we optimized for a CLS score of 0. 

A web page optimized for CLS score of 0

CLS metric is the first step to make websites more visually stable. It’s evolving and in the coming years, based on data analysis it would tell us more about its impact on User Experience.