How To Fix Cumulative Layout Shift (Examples & Best Practices)

Last updated on Sep 8th, 2021 | 9 min

The Cumulative Layout Shift (CLS) metric measures how much unexpected layout shifts affect the user experience on a page. These layout shifts occur when content moves around without prior user input.

In this article, you'll learn how to solve the most common CLS problems.

Reducing your CLS will benefit your website’s UX and SEO, especially now that the Core Web Vitals are part of Google's ranking algorithm.

Here’s a quick overview of everything covered here:

 

Let’s get started.

What Causes CLS Problems?

A few elements often cause unexpected layout shifts and worsen your CLS score:

1. Images and videos with no dimensions (width and height attributes)

Loading image without dimensions

2. Ads, embeds and iFrames without reserved space

Example of layout shift due to an ad

3. Web fonts causing flashes of unstyled or invisible text - FOUT and FOIT

FOUT

While this metric was changed to be more neutral to the time on page, these elements remain a constant source of CLS issues.

Other elements can also cause layout shifts, so you should learn how to analyze and debug CLS issues. If you’re interested, just skip ahead to the “Measuring and Debugging CLS Problems” section.

Before diving into specific solutions, we have to discuss the two most important principles for avoiding layout shifts.

The Most Important Thing to Avoid

 

Principle 1: Avoid injecting new content at the top of a page over already existing content unless in reaction to user input.

 

This is the easiest and most common way to ruin your CLS score. Here’s what happens when an ad is placed at the top of a page:

CLS example

Source - creativebloq.com

The ad caused everything on the page to move, i.e., there was a massive unexpected layout shift. That’s the whole problem with inserting content at the top.

Many elements can cause this issue, including:

  • Ads;

  • Pop-ups;

  • Promo banners;

  • Search bars.

Now, if you’re in a situation where you absolutely have to place new content at the top of the viewport, there are ways to mitigate the damage.

Which brings us to the second principle.

Add Dimensions to Avoid Layout Shifts

 

Principle 2: Any content that comes in without user input should have enough space reserved.

 

That’s why width and height attributes are your best friends when it comes to avoiding CLS issues.

Using these attributes in the HTML markup helps the browser allocate enough space for the content in advance. This reduces layout shifts when that content appears on the page.

Or in other words:

When you have to break the first principle (don’t insert content over existing content), apply the second principle (reserve enough space in advance) to avoid CLS issues.

Now let’s move on to the specific tips.

How to Improve Your CLS Score

Add width and height Attributes to Images and Videos

As I already said, these attributes let the browsers know how much space they must allocate for each image or video.

Image with dimensions loading

This is probably the easiest way to fix current CLS issues and prevent potential ones. It’s as simple as adding a few lines to the HTML markup:

Width and height attrbitues in HTML

At NitroPack, we call this Preemptive Image Sizing and we do it without adding width and height attributes. Regardless of the method, the important thing is to alert the browser so it can reserve space in advance.

Some websites also use placeholders and skeleton UIs for even better image loading.

For example, developers can place low-quality placeholder images with a similar background to the final image.

Loading images with placeholder

Techniques like these don’t prevent CLS problems alone (you still need width and height attributes!), but they’re great for improving perceived performance.

In the video below, Addy Osmani talks about optimizing CLS for an eCommerce store that uses placeholders for their product images:

 

Their approach is a bit more advanced, but it’s still worth considering, especially if you have lots of products on your site.

Reserve Space for Ads, Embeds and iFrames

Let’s go back to our example of an ad causing massive layout shifts:

Source - forbes.com

This is a common problem, especially for news websites, as their business model relies on ad revenue.

Ads can cause layout shifts during different points of their lifecycle since they're usually loaded asynchronously. I recommended checking out Google’s documentation for more details on this issue if you’re working with their Publisher Tags.

In general, the solution with ads is to statically reserve space for them in advance. Doing this ensures the ad container is styled correctly before the ad library loads.

You can look at historical data to determine how large the reserved spaces should be for each ad.

Here’s an example of how ads with enough reserved space load:

Loading ads with width and height attributes

Source - yahoo.com

As you can see, ads on Yahoo's site (at least above the fold) don’t move the content below or around them.

Now, in some cases, the ad network might not deliver an ad to the container. If that happens, don’t collapse the container, as that will cause a layout shift. Use a placeholder instead.

Also, if your website receives an ad larger than the reserved slot, use the overflow: hidden property. It's a great failsafe for avoiding CLS problems that might be hard to detect otherwise.

In short:

  • Use width and height in the HTML markup to reserve space for ads in advance;

  • Don’t collapse the container if the ad network doesn’t serve an ad;

  • Use overflow: hidden to prevent larger ads from overflowing the container.

This is part of the approach that Yahoo takes to avoid layout shifts:

Ads space reserved example

For embeds, you should also use a placeholder or fallback.

Just make sure to analyze the final element with DevTools to know how much space it takes up.

Analyzing embeds with DevTools

Techniques like reserving space and using placeholders/fallback are also necessary when injecting dynamic content. Apply them whenever you need to insert elements without prior user input.

Optimize Font Delivery (FOUT/FOIT)

Unoptimized web font delivery can cause huge layout shifts.

For example, when a fallback font is switched with the downloaded web font, we have a “flash of unstyled text” or FOUT.

FOUT Example

In other cases, “invisible” text is displayed before the web font is ready. That’s called a “flash of invisible text” or FOIT.

Before diving into the specifics, it’s worth noting that there’s no perfect strategy for dealing with web fonts. That’s why new font descriptors are currently proposed in the draft for CSS Font Module Level 5.

Addy Osmani also recently tweeted about a possible size-adjust CSS descriptor that should help reduce layout shifts. In short, be on the lookout as new strategies for dealing with font loading should be available soon.

As of today, using font-display: optional in combination with link rel: “preload” for your most important fonts is generally regarded as the best overall strategy.

The reason why it works is a long topic, but the TL;DR is this:

The optional value won’t cause a re-layout when the web font is ready. At the same time, the preloaded font will likely meet the first paint, ensuring no layout shifts occur.

To preload a font, you have to add a few attributes to the head tag of the page, like this:

Preload fonts in HTML

Adding the like as=”font”, type=”font/woff2” and crossorigin helps the browser prioritize resources when rendering the page.

Again, if you want an in-depth explanation of how and why this method works, check out:

Measuring and Debugging CLS Problems

In some cases, it might not be obvious what causes a layout shift.

Fortunately, there are a few tools you can use to analyze any CLS problem.

Chrome’s DevTools

Open a page you want to analyze, right-click and select “Inspect”.

Next, click on “More Options” and go to “Rendering”.

After that, select the “Layout Shift Regions” options and reload the page.

As the page loads, all of the shifting elements will be highlighted in blue:

Source - forbes.com

You can also use the “Performance” panel and hover over the “Layout Shift” area in the “Experience Section”.

Keep in mind that DevTools won’t tell you if a shift is “good” or “bad”. Don’t be alarmed if something moves around after you click on a button or scroll down the page - that doesn’t contribute to CLS, as the layout shift is initiated by a user.

Lighthouse Audit

The Lighthouse audit shows you which elements contribute the most to your CLS score.

Again, click “Inspect” on the page, but this time go to “Lighthouse”.

Lighthouse audit in DevTools

Click on “Generate report” and wait for Lighthouse to work its magic.

Once it's ready, go to the “Diagnostic” section and look for the “Avoid large layout shifts” warning. When you click on it, it will show you which elements contribute the most to layout shifts.

Layout Shift GIF Generator

Lastly, a personal favorite of mine is this Layout Shift GIF generator.

It’s really easy to use as it only requires a URL and it provides a GIF with all of the layout shifts on the page. The results look like this:

CLS GIF Generator

You can also use it to check a mobile (Nexus 5X) version of the page.

On top of that, you can use a command line version of the tool by installing it directly from NPM. Check out the GitHub page for more information.

Other Tips and Best Practices for Dealing with the Core Web Vitals

After fixing your CLS score, it’s a good idea to periodically look at field data to detect potential problems.

Field data are gathered by the Chrome User Experience Report (CrUX). These data show how real users experience your site.

You can find field data directly below your overall score in PageSpeed Insights:

Field Data in PSI

If PageSpeed Insights doesn’t display this field due to lack of data, you can use different tools to access the CrUX dataset:

Core Web Vitals report in Google Search Console

Source - Google Search Console’s Core Web Vitals report

Which tool you choose depends on your preference. The important thing is to be aware of any CLS issues that your visitors might be having.

And since Google uses the previous 28-day period to determine whether your site passes the Core Web Vitals audit, you should check the field data at least once a month.

Finally, always look for unexpected layout shifts after code updates to your site. These shifts can sneak in during development and remain unnoticed for a long time.

Evgeni Yordanov
Content Lead

Evgeni writes about site speed and makes sure everything we publish is awesome.