Cumulative Layout Shift (CLS) measures how much visible content unexpectedly moves around while the page loads. Every time an element shifts position without user interaction, it contributes to your CLS score.
High CLS creates frustrating experiences:
Clicking a button only to have the page shift and hit something else
Losing your place while reading product descriptions
Accidentally adding the wrong item to cart because a button moved
CLS is one of Google's Core Web Vitals and directly impacts:
User experience: Visitors aren't frustrated by jumping content
Search engine rankings: Google uses CLS as a ranking signal
Conversion rates: Stable pages feel more trustworthy
CLS thresholds
Rating | Score | What it means |
Good | ≤ 0.1 | Page layout is stable |
Needs Improvement | 0.1 – 0.25 | Some unexpected movement |
Poor | > 0.25 | Significant layout instability |
Unlike LCP and INP which are measured in time, CLS is a unitless score based on how much content shifts and how far it moves.
Understanding the CLS detail page
The CLS detail page provides deep insights into what's causing layout shifts on your store.
P75 score card
Shows your 75th percentile CLS, meaning 75% of your page views have this score or better. This is the score Google uses for search ranking signals. The card also displays a distribution bar showing what percentage of page views fall into Good, Needs Improvement, and Poor categories.
CLS distribution
A histogram showing how CLS values are distributed across all page views. In an ideal scenario, most values cluster in the "Good" range (under 0.1). A long tail extending into "Poor" territory indicates some visitors are experiencing significant layout instability.
CLS timeline
A line chart showing your P75 CLS score over time. The chart displays two lines:
Current period: Your CLS scores for the selected date range
Previous period: The equivalent prior period for comparison (e.g., if viewing the last 7 days, you'll see the 7 days before that)
Use this to:
Spot regressions after theme changes or app installations
Confirm that fixes are working by comparing to the previous period
Correlate shifts with traffic patterns or marketing campaigns
CLS rating over time
A stacked area chart showing the daily percentage of page views rated Good, Needs Improvement, or Poor. This complements the P75 timeline by showing the full distribution, not just the 75th percentile.
CLS by country
A world map showing CLS performance by geographic region. CLS is less affected by geography than LCP or TTFB since it measures layout stability rather than load time. However, region-specific banners, cookie consent dialogs, or localized content can cause shifts in certain countries.
CLS elements table
This is your most actionable debugging tool. It lists the actual DOM elements that shifted, grouped by element selector. For each element, you'll see:
Column | What it measures | What it tells you |
Shift value | How much this element contributes to CLS | Higher values indicate bigger or more frequent shifts |
Shift time | When during page load the shift occurred | Early shifts suggest images without dimensions; late shifts suggest dynamic content |
Elements are sorted by page views, so the most frequently shifting elements appear first.
Top pages with CLS score
Pages with the most traffic and their CLS scores. Focus optimization efforts here for maximum impact.
Poorest CLS score pages
Pages with the worst CLS scores, regardless of traffic. These may indicate specific template or content issues worth addressing.
Common CLS issues and how to fix them
Images without dimensions
The most common cause of CLS. When images don't have explicit dimensions, the browser can't reserve space for them—causing content below to jump when the image loads.
<!-- Bad: No dimensions -->
<img src="product.jpg" alt="Product">
<!-- Good: Explicit dimensions -->
<img src="product.jpg" alt="Product" width="400" height="300">
<!-- Good: Inline CSS aspect ratio -->
<img src="product.jpg" alt="Product" style="aspect-ratio: 4/3; width: 100%;">
For Shopify themes, ensure your image snippets include width and height attributes:
{{ product.featured_image | image_url: width: 800 | image_tag:
width: product.featured_image.width,
height: product.featured_image.height,
alt: product.featured_image.alt }}
Dynamically injected content
Content that loads after the initial page render—like promotional banners, newsletter popups, or app widgets—can push existing content down.
Fixes:
Reserve space: Use
min-heighton containers that will hold dynamic contentUse skeleton loaders: Show placeholder content that matches the final size
Load below the fold: Insert dynamic content where it won't shift visible elements
Use overlays: Display popups and notifications as overlays rather than inline elements
Web fonts causing FOUT/FOIT
When web fonts load and replace fallback fonts, text can reflow if the fonts have different sizes. This is known as Flash of Unstyled Text (FOUT).
Fixes:
Match fallback fonts: Choose fallback fonts similar in size to your web fonts
Use font-display: swap: Allow text to render immediately with fallbacks
Preload critical fonts: Add to your theme's
<head>:
<link rel="preload" as="font" type="font/woff2" href="{{ 'font.woff2' | asset_url }}" crossorigin>Consider system fonts: System font stacks load instantly with zero CLS
Animations that trigger layout
Animating properties like height, margin, or padding causes the browser to recalculate layout, shifting surrounding content. When these animations happen automatically (not from user interaction), they contribute to CLS.
Common examples: auto-expanding promotional banners, carousel slides with varying heights, or content that animates on scroll.
/* Bad: Banner animates height on page load */
.promo-banner {
animation: expandBanner 0.5s forwards;
}
@keyframes expandBanner {
from { height: 0; }
to { height: 60px; }
}
/* Good: Reserve space, animate content visibility */
.promo-banner {
height: 60px; /* Space always reserved */
}
.promo-banner-content {
animation: fadeIn 0.5s forwards;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
Composited animations using transform and opacity don't trigger layout recalculations and won't count toward CLS.
Note: Layout shifts within 500ms of a user interaction (like clicking an accordion) are excluded from CLS, so user-triggered expand/collapse animations don't affect your score.
Late-loading app widgets
Third-party apps often inject content after page load—chat widgets, review badges, announcement bars—which can shift existing content.
Fixes:
Reserve space with minimum heights: If you know a widget will load, reserve its space
Use fixed or absolute positioning: Chat widgets and floating buttons that overlay content don't cause layout shifts
Choose apps wisely: Look for apps that advertise zero CLS impact
Remove unused apps: Each app is a potential source of layout shifts
Note: InstaIndex is designed with performance in mind. We don't inject any visible content into your pages, so we never cause layout shifts.
Ads and promotional banners
If you display ads or promotional banners, they can cause significant CLS if space isn't reserved.
Fixes:
Set explicit dimensions: Always specify width and height for ad containers
Use sticky positioning: Sticky headers/footers don't shift content
Avoid inserting at the top: Content inserted at the top of the page causes the most jarring shifts
Understanding shift timing
The Shift time column in your CLS elements table tells you when shifts occur:
Early shifts (0-1 second): Usually caused by images without dimensions or fonts loading
Mid-load shifts (1-3 seconds): Often caused by lazy-loaded content or third-party scripts
Late shifts (3+ seconds): Typically from apps, chat widgets, or deferred content
Understanding when shifts happen helps identify the cause:
If shifts happen immediately, check your images and fonts
If shifts happen after a few seconds, investigate third-party apps and lazy-loaded content
Quick wins for better CLS
Add dimensions to all images in your theme—this alone often fixes most CLS issues
Check your CLS elements table to identify the biggest offenders
Preload your web fonts to prevent font swap shifts
Review recently installed apps for ones that inject visible content
Use transform for animations instead of layout properties
Related articles
