One of the most frustrating things that happen to us when browsing a website is unexpected and sudden changes on a page.
Such changes can be a suddenly appearing popup, content that shifts suddenly in the middle of reading, or a button that changes its position just when we’re about to click on it.
Google also dislikes these sudden changes as they negatively impact user experience. That’s why Google introduced a metric called Cumulative Layout Shift (CLS) which measures the frequency of changes occurring while the browser is rendering the page.
What is Cumulative Layout Shift (CLS)?
In short, CLS measures the sum of individual changes that happen within the layout throughout the lifespan of a specific page (even if layout changes occur after some time).
The CLS metric is a part of Core Web Vitals and measures the stability (or instability) of a specific page. Before we continue, take a look at the following video:
The video excellently illustrates what an undesirable bad layout shift is. I’m sure many of you have encountered similar situations in the past, and just as you’d like to avoid them, Google also wants to address them, as they affect the user experience.
CLS assesses the ratio between the affected portion within the viewport due to layout changes and the distance the shifted elements moved.
Because of its impact on user experience, CLS’s score has a certain influence on your site’s ranking on Google and search engines, along with the following crucial core vitals metrics:
- First Contentful Paint (FCP) metric.
- First Input Delay (FID) or Total Blocking Time (TBT) metric.
- Largest Contentful Paint (LCP) metric.
As always, it’s important to note that the goal is to achieve a good user experience, not just scores. Those scores are only indicators of actions to take or issues to address.
Expected Layout Changes vs. Unexpected Changes
It’s clear to all of us that not all layout changes are negative and detrimental to user experience. Generally, if the layout change occurs due to a user-initiated action, it is considered an expected change (or a positive change).
For instance, a positive change could be clicking on the mobile menu (the hamburger menu) to open the site’s navigation. Another example is clicking on a link or button at the top of the page that slightly shifts the content downward.
Google can differentiate between positive and negative layout changes. Any change occurring within 0.5 seconds (500ms) since the user’s last interaction isn’t included in your CLS score.
For instance, in the earlier example, for the navigation menu located outside the canvas and that specific element, it has 0.5 seconds to appear on the screen from the moment the user performs that interaction requiring the change.
On the other hand, unexpected (negative) changes are a completely different story. The video below vividly demonstrates what a bad layout shift is. I’m sure many of you have dealt with such frustrating scenarios on a daily basis:
So, What’s a Good CLS Score and What Should We Aim For?
Following Google’s guideline for the sake of good user experience, you should aim for a CLS score lower than 0.1 and make sure it doesn’t exceed 0.25. In other words:
- Good – CLS less than 0.1
- Needs Improvement – CLS between 0.1 and 0.25
- Poor – CLS higher than 0.25
Note that unlike other core vitals metrics, CLS isn’t measured in time.
The formula for calculating the score is as follows:
It’s important to note that for mobile layout changes, the impact is more significant due to the smaller screen area of mobile devices. When you check the CLS score, you’ll notice a different score for mobile and desktop.
How to Check the CLS Score of a Specific Page?
You can measure CLS both with field data and lab data using several tools at your disposal. For instance, PageSpeed Insights, the recently upgraded GTmetrix tool, WebPageTest that we love, and even via Google Search Console (under the Core Web Vitals report). These are the three most common tools for checking CLS score and these layout changes.
You can also use Chrome Lighthouse or the DevTools in Chrome as lab tools.
However, even though these tools display your CLS score, the real testing of layout changes isn’t an easy task and doesn’t end with these tools.
This is because testing the data in a development environment provides a different experience than testing on the live site, since the relevant assets (CSS, fonts, images, etc.) are already cached in the live site’s browser memory.
Therefore, in this case, layout changes will happen much faster, making it difficult to spot them with an untrained eye. You might notice several layout changes occurring, but you might struggle to identify all of them.
So, how can you perform a thorough test for layout changes on a page? Here are two recommended methods…
First Method – Layout Shift Regions
In the first method, we intentionally slow down the site’s loading speed for testing purposes. When the site loads extremely slowly, you can observe which elements changed and how many layout changes occurred on the page.
Dynamic elements will also load slowly, and all layout changes will be visible. You can do this using Chrome DevTools as follows:
- Open Chrome DevTools (by pressing F12) on the page you want to test the layout changes for and navigate to the Network tab.
- Click on the dropdown that says “Online” and change the setting to Slow 3G, for example, to simulate a slower internet connection.
After setting the connection speed to slow, go to the Elements tab and then proceed to the “More Tools” section (inside the three-dot menu) and select “Rendering.”
At the bottom, you will see “Layout Shift Regions.” Activate this option and then reload the page. Now, you’ll be able to see areas where layout changes occur highlighted in blue.
You can also see the specific element causing the layout shift in the PageSpeed Insights report.
Another way to check layout shifts is by navigating to the Performance tab in Chrome DevTools and clicking on “Start profiling and reload page.” This action will refresh the page and provide you with a profile report titled “Experience.”
There, you can select a specific “Layout Shift” and the HTML element causing the layout shift will be highlighted and displayed on the page itself.
If you want to see a summary of the shift, as well as the original and new positions of the moving object, you can click on “Layout Shift.”
How to Improve Your CLS Score
Now that we know how to check the CLS score and layout shifts on a website, let’s look at some common issues affecting that score and suggest solutions:
1. Loading Font Causes FOIT/FOUT
Not surprisingly, fonts are among the main performance-related culprits affecting CLS. Most modern websites use at least one web font (from Google Fonts or other sources), if not more.
Since these web fonts have varying letter spacing and sizes compared to the browser’s default fonts, layout shifts occur when web fonts load. You can’t completely eliminate this issue, but you can certainly mitigate it.
To minimize the issue, you can pre-load your web fonts (rel = preload) so that font loading gets higher priority during page load. It’s also recommended to host web fonts locally on your server, though it’s not advisable if your hosting server isn’t fast and reliable.
font-display property also helps combat FOUT & FOIT effects that impact your CLS score. More about this property in the article about the font-display property.
Additionally, it’s recommended to use aggressive caching and a good CDN for hosting static assets like fonts. The CDN serves assets from the closest and fastest network location, resulting in faster loading and minimized layout shifts caused by fonts.
Remember that preloading fonts might negatively impact the Largest Contentful Paint (LCP) metric, as explained in my article on how to improve LCP – the loading time of the main content of a page.
Embeds and iFrames
Embeds allow you to incorporate and display content from other sites on a page, such as YouTube videos, Google Maps, Instagram posts, and more. There are various embedding methods, for example:
- Embedded HTML code
- Script tag with HTML fallback
One issue is that most embeddable applications do not include the exact dimensions of the embedded content upfront. For instance, if you embed a tweet, it might include only text or text + an image.
Since the exact dimensions are unknown, most platforms offering embeds do not include dimensions in their code. As a result, when the embedded content loads, it might cause significant layout changes.
When using embeds, you can improve the CLS score by setting the required dimensions upfront and then using a placeholder or fallback content.
To determine the required embed height, you can check the final embed using Chrome’s Developer Tools. This way, you can set placeholder dimensions so that there’s enough space for the embed (when it loads) without causing layout changes.
Widgets and certain platforms like Google Maps allow you to set the embed dimensions in a way that won’t cause issues in this regard.
Dimensionless Images and SVGs
Images are another very common cause of unexpected layout shifts, especially when dealing with dimensionless images—images that don’t have fixed width and height.
When you visit a page with dimensionless images, the browser doesn’t allocate a special space for these images when they load. As a result, these images might suddenly cause layout shifts, moving text or previously loaded content.
Images are usually loaded after textual content, as images have larger file sizes compared to HTML and CSS.
One way to avoid this is by defining the width and height of the images on the website. This can be an issue in responsive design, so a better approach is to use aspect ratios in CSS.
By using the aspect ratio of width and height, you can specify one dimension (either height or width), so you won’t encounter layout problems in context.
SVG images behave slightly differently and are scaled to the dimensions of the HTML element containing them. Before the change occurs, SVG images tend to load in their full size, causing sudden shifts and hence affecting CLS.
To solve this, you need to define the desired width and height in the SVG image code. This way, the SVG will load with the exact dimensions you want, preventing undesirable layout shifts.
Here’s an example of SVG without defined dimensions. After opening the SVG in a text editor and adding the following width and height you can see the same SVG image with the dimensions we specified. Pay attention to the added width and height.
‹svg xmlns="http://www.w3.org/2000/svg" width="40px" height="40px" viewBox="...
There are many other specific methods, but this optimization should be a good starting point, as the browser will reserve space for image loading and prevent unwanted layout changes.
Advertisements are among the major contributors to layout shifts. Most ad platforms use dynamic sizes instead of fixed dimensions, which can lead to performance and layout issues.
The reason behind this is to improve ad performance and click-through rates (CTR) based on ad size. Since ad content is served from different servers, their loading can be slower compared to other page elements.
There are several recommended approaches to mitigate or eliminate layout shifts caused by ads. One of them is allocating space in advance for the ad. This can be achieved using CSS to style the element for dynamic ad content.
You might, for instance, maintain the maximum size, but be cautious, as this approach could leave empty space around if smaller ads load.
Also, be aware of scenarios where no ad is displayed even though you reserved space. My advice is to display a placeholder, as the reserved area might shrink if no content is loaded…
In conclusion, there isn’t a one-size-fits-all solution regarding ads. In most cases, it depends on your ad network and the historical data of displayed ads to determine the best approach to save space for ad content.
Every website has dynamic content. We’ve all seen different types of it – related posts, newsletter signup forms, sticky bars with messages, and more.
Fortunately, the simplest way to avoid layout shifts caused by dynamic content is to insert the dynamic content beneath existing content, not above it. However, the exception is when you need to display dynamic content above existing content due to user interaction.
If avoiding placing dynamic content below existing content isn’t possible, ensure you allocate enough space for it.
Remember that I previously mentioned what Google defines as good layout shifts (expected layout shifts)? Any layout shift in response to user interaction is a good layout shift.
However, your website should load within 0.5 seconds for all that’s required for a specific user interaction. This ensures that layout shifts won’t affect the CLS score of your specific page/site. Optimizing various speed metrics for your website is important to prevent adverse effects on the CLS score of your page/site.
Regarding animations, Google’s recommendation for achieving optimal CLS is to use CSS Transforms in CSS to prevent unexpected layout shifts. This is mainly because these CSS properties don’t cause geometric changes, unlike other CSS properties related to animation.
If you’re using Lottie animations, with elements sliding onto the screen from left to right in fade-in/fade-out effects, my recommendation is still to define the element’s height in a way that won’t cause poor or unexpected layout shifts.
CLS optimization is a ongoing process that requires high involvement. While it might not significantly impact search engine rankings compared to other core metrics right now, as Google collects more CLS-related field data, it will become an important metric.
Moreover, reducing or eliminating layout shifts will lead to improved user experience, potentially increasing conversions and click-through rates, which are equally important metrics. Therefore, regardless of your perspective, optimizing CLS is an important and worthwhile endeavor.