CLS element movement
This health check detects individual elements that cause cumulative layout shift (CLS) based on real user data.
Instead of just showing that CLS is high, this check pinpoints the specific elements moving on the page, so you can fix the root cause.
Each todo represents a single element that shifts significantly for a specific device type.
About this check
When this check is triggered
You’ll see this check when:
- An element contributes significantly to CLS
- The issue is consistent across real users
- There are enough events (minimum threshold applied)
- The impact is visible in higher percentiles (p75, p85, p90)
What you’ll see
Each todo includes:
- Element identifier
- Device type (desktop, mobile, tablet)
- Impact based on real user sessions
Example:
Element moved significantly on mobile
The element.hero-banner imgis moved around heavily on mobile.
Why this matters
CLS directly impacts:
- User experience (unexpected jumps)
- Conversion rates
- Core Web Vitals performance
Even small shifts can feel disruptive, especially on mobile.
More context on web.dev and RUMvision CLS blogpost.
How to fix it
Most CLS issues come from:
- Images or videos without dimensions
- Ads, embeds, or iframes loading late
- Fonts causing layout changes (FOIT/FOUT)
- JavaScript injecting content above the fold
- Dynamic UI components (banners, cookie notices)
Possible causes and fixes:
1. Reserve layout space
Ensure elements have a defined size before they load.
What to do
- Add
widthandheightattributes to images - Use
aspect-ratioin CSS for responsive media - Reserve space for ads and embeds
Example
img alt="Hero" height="400" src="hero.jpg" width="800"
.video {
aspect-ratio: 16 / 9;
} 2. Stabilize UI updates
Avoid pushing content down after initial render.
What to do
- Do not inject banners above existing content
- Use placeholders or skeleton loaders
- Render critical UI elements immediately
For example, instead of:
setTimeout(() => {
showCookieBanner();
}, 2000); Use:
- Reserved space
- Or overlay instead of pushing layout
3. Handle fonts properly
Web fonts can cause subtle but frequent layout shifts.
What to do
- Preload critical fonts
- Use
font-display: swap - Match fallback font metrics to the web font where possible
- For example with more modern solutions like CSS Font descriptors
4. Sticky header and filter bars
Elements that become sticky on scroll often do not reserve space for the underlying content. This causes the content below to shift when the element becomes sticky.
What to check
- Toggling an element from
position:relativetoposition:fixedon scroll - Use modern and browser compatible alternatives like
position:stickywithin scrollable containers - Alternatively, apply
position:absoluteorfixedfrom the start and use a placeholder with matching height.
5. Use hardware accelerated animations
Animations on the main thread can easily trigger layout shifts.
What to check
- Avoid animating all properties (e.g.
transition: all 0.2s ease) - Limit animations to transform properties (e.g.
transition: transform 0.2s ease) - To then use
transform:translateY(-100px)instead oftop:-100pxto animate positional changes of elements
6. Audit third-party scripts
Third-party scripts are a common source of layout shifts.
What to check
- Ads resizing after load
- Ad rotating system that is clearing contents in between ad-rendering
- A/B testing tools injecting DOM changes
- Chat widgets appearing above content
- Cookie or newsletter widgets that are sliding into screen with wrong CSS properties (see 5. Use hardware accelerated animations)
7. Dynamic content
Avoid layout shifts from dynamic content by both 3rd and 1st party scripts.
What to check
- Content inserted via API after initial render
- Hydration mismatches where server HTML differs from client render
- Late-loading recommendations or related content
- Infinite scroll appending above fold content
- YouTube, maps, social embeds resizing after load
8. Scrollbar jitter
Avoid shifts caused by scrollbar appearance
What to check
- Layout width changes when scrollbar appears/disappears
Remediation:
html {
overflow-y: scroll;
} or a Newly Available solution:
scrollbar-gutter: stable;
Further debugging
How to approach this in RUMvision
- Open the todo
- Inspect the element selector
- Reproduce the issue:
- Use Chrome DevTools → Performance panel
- Enable “Layout Shift Regions”
- Identify what triggers the movement
- Apply one of the fixes above
- Monitor improvement in the next 7 days
Pro tip
Focus on:
- both above and below-the-fold elements, while you may want to start with above-the-fold shifts
- Mobile first (usually worse CLS)
- Recurring components (headers, hero blocks, ads)
Fixing one component can resolve multiple CLS issues at once.