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 help improve your website’s UX and SEO once the Core Web Vitals become ranking factors.
Let’s get started.
Three types of elements cause unexpected layout shifts most often:
1. Images and videos with no dimensions (width and height attributes)
2. Ads, embeds and iFrames without reserved space
3. Web fonts causing flashes of unstyled or invisible text - FOUT and FOIT
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.
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:
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:
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.
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 ads, pop-ups, or any dynamic 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.
As I already said, these attributes let the browsers know how much space it must allocate for each image or video.
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:
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.
Techniques like these don’t prevent CLS problems (you still need width and height attributes!), but they’re great for improving perceived performance.
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.
The solution here is to statically reserve space for the ad 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:
Source - yahoo.com
As you can see, ads on yahoo.com (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.
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:
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.
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.
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.
In other cases, “invisible” text is displayed before the web font is ready. That’s called a “flash of invisible text” or FOIT.
To solve both issues, use font-display: optional in combination with link rel: “preload” for your most important fonts.
The reason why this 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:
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 this article on preloading web fonts.
In some cases, it might not be obvious what causes of a layout shift.
Fortunately, there are a few tools you can use to analyze any CLS problem.
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.
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”.
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.
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:
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.
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 use different tools to access the dataset:
BigQuery - requires a Google Cloud project and SQL skills;
The Core Web Vitals report in Google Search Console - very beginner-friendly, useful for marketers, SEOs and webmasters.
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.
Finally, always check for layout shifts after code updates to your site. These shifts can sneak in during development and remain unnoticed for a long time.