Fix CLS Issues on Carrd (Layout Shift) | OpsBlu Docs

Fix CLS Issues on Carrd (Layout Shift)

Stabilize Carrd single-page layouts by sizing container sections, preloading Google Fonts, and reserving space for embedded widgets.

Cumulative Layout Shift (CLS) measures visual stability during page load. This guide provides Carrd-specific solutions to eliminate layout shifts and maintain a stable, professional user experience.

General Guide: See Global CLS Issues for universal concepts and fixes.

What is CLS?

Cumulative Layout Shift (CLS) is one of Google's Core Web Vitals that measures visual stability. It quantifies how much unexpected layout shift occurs during the page load process.

CLS Thresholds

  • Good: ≤ 0.1
  • Needs Improvement: 0.1 - 0.25
  • Poor: > 0.25

Carrd Baseline Performance

Out of the box, Carrd sites typically achieve:

  • CLS: 0.0 - 0.05 (excellent)
  • Visual Stability: Very stable layouts
  • Minimal shifts: Clean, predictable rendering

If your Carrd site has CLS > 0.1, optimization is needed.

Common CLS Causes on Carrd

Layout shifts on Carrd sites typically come from:

  1. Images without dimensions: Browser doesn't know size until loaded
  2. Web fonts loading: Text reflows when fonts load
  3. Embed elements: Third-party widgets shifting layout
  4. Dynamic content: JavaScript-injected content
  5. Ads or widgets: Marketing embeds without reserved space
  6. Custom CSS: Transitions or animations causing shifts

Diagnosing CLS Issues on Carrd

Step 1: Identify Layout Shifts

Use Google PageSpeed Insights:

  1. Go to PageSpeed Insights
  2. Enter your published Carrd site URL
  3. Click Analyze
  4. Review CLS score
  5. Check Avoid large layout shifts in diagnostics
  6. See which elements are shifting

Step 2: Visual Inspection

Use Chrome DevTools:

  1. Open your published Carrd site
  2. Press F12 > Lighthouse
  3. Check Performance
  4. Click Generate Report
  5. Scroll to Diagnostics
  6. Look for layout shift screenshots

Step 3: Experience Builder

Use Chrome's Layout Shift Regions:

  1. Press F12 > Console
  2. Paste this code:
let cls = 0;
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log('Layout Shift:', entry.value, 'Total CLS:', cls);
      console.log('Shifted elements:', entry.sources);
    }
  }
}).observe({type: 'layout-shift', buffered: true});
  1. Reload page
  2. See exactly which elements shift and when

Carrd-Specific CLS Optimizations

1. Fix Image Dimensions

Images without explicit dimensions cause layout shifts when they load.

Set Image Dimensions in Carrd

For image elements:

  1. Select the image in Carrd editor
  2. In image settings, note the display dimensions
  3. Add an embed element near the image
  4. Add explicit dimensions via CSS:
<style>
/* Replace .image-id with your image's ID or class */
.image-element {
  width: 800px;
  height: 600px;
}

/* Or use aspect ratio (modern browsers) */
.image-element {
  aspect-ratio: 4 / 3;
  width: 100%;
}
</style>

Best practice for responsive images:

<style>
/* For all images */
img {
  max-width: 100%;
  height: auto;
}

/* Specific aspect ratio containers */
.hero-image-container {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9; /* Adjust to your image ratio */
}

.hero-image-container img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
</style>

Add this in a Style embed at the top of your page.

Background Images

For section background images:

<style>
/* Reserve space for sections with background images */
#section-hero {
  min-height: 600px; /* Set explicit min-height */
}

@media (max-width: 768px) {
  #section-hero {
    min-height: 400px; /* Smaller on mobile */
  }
}
</style>

In Carrd: Find your section ID by inspecting it in browser DevTools.

2. Optimize Web Font Loading

Web fonts cause layout shifts when text reflows after font loads.

Font Display Swap

If using custom fonts, ensure font-display: swap is set:

<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">

Note the display=swap parameter.

Preload Critical Fonts

For fonts used above the fold:

<link rel="preload" as="font" type="font/woff2" href="https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiA.woff2" crossorigin>

Add in embed element at top of page.

Font Loading Strategy

Prevent font-based layout shifts:

<style>
/* Ensure fallback font matches custom font dimensions */
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  /* Use similar fallback font to minimize reflow */
}
</style>

System Fonts Alternative

For zero CLS from fonts:

<style>
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* System fonts = no loading = no shift */
}
</style>

3. Reserve Space for Embeds

Third-party embeds (widgets, social feeds, etc.) often cause layout shifts.

Fixed Height Containers

Wrap embeds in containers with fixed heights:

<div style="min-height: 400px;">
  <!-- Your embed code here -->
  <script src="https://widget.example.com/embed.js"></script>
</div>

Common Embed Heights

Reserve appropriate space for popular embeds:

  • Instagram feed: 500-600px
  • Twitter embed: 400-500px
  • YouTube video: Use 16:9 aspect ratio
  • Calendly: 700px
  • Gumroad embed: 300-400px
  • Chat widget: Usually fixed position, no space needed

YouTube/Video Embed Wrapper

Prevent shift with aspect ratio wrapper:

<style>
.video-container {
  position: relative;
  width: 100%;
  padding-bottom: 56.25%; /* 16:9 aspect ratio */
  height: 0;
  overflow: hidden;
}

.video-container iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>

<div class="video-container">
  <iframe src="https://www.youtube.com/embed/VIDEO_ID" frameborder="0" allowfullscreen></iframe>
</div>

4. Avoid Layout-Shifting Animations

Certain CSS properties cause layout shifts when animated.

Safe CSS Properties

These DON'T cause layout shifts:

  • transform
  • opacity
  • filter

These DO cause layout shifts (avoid animating):

  • width, height
  • margin, padding
  • top, left, right, bottom (on static elements)
  • font-size

Use Transform Instead

Bad (causes CLS):

.element {
  transition: margin-top 0.3s;
}
.element:hover {
  margin-top: -10px;
}

Good (no CLS):

.element {
  transition: transform 0.3s;
}
.element:hover {
  transform: translateY(-10px);
}

5. Dynamic Content Handling

JavaScript-injected content can shift layout.

Reserve Space for Dynamic Content

If loading content via JavaScript:

<div id="dynamic-content" style="min-height: 200px;">
  <!-- Content will load here -->
</div>

<script>
// Load content
fetch('/api/content')
  .then(response => response.json())
  .then(data => {
    document.getElementById('dynamic-content').innerHTML = data.html;
  });
</script>

The min-height prevents shift when content loads.

Skeleton Screens

Show placeholder while loading:

<style>
.skeleton {
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: loading 1.5s infinite;
  border-radius: 4px;
}

@keyframes loading {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
</style>

<div id="content-area">
  <!-- Show skeleton while loading -->
  <div class="skeleton" style="width: 100%; height: 100px; margin-bottom: 10px;"></div>
  <div class="skeleton" style="width: 80%; height: 20px;"></div>
</div>

<script>
// Replace skeleton with actual content after load
window.addEventListener('load', function() {
  document.getElementById('content-area').innerHTML = actualContent;
});
</script>

6. Carrd Form Elements

Forms can cause CLS if not handled properly.

Set Form Heights

<style>
/* Prevent form from shifting layout */
form {
  min-height: 400px; /* Adjust based on your form */
}

/* Or specific form */
#form-contact {
  min-height: 500px;
}
</style>

Form Success/Error States

When showing success/error messages:

<style>
/* Reserve space for form messages */
.form-message {
  min-height: 50px;
  transition: opacity 0.3s;
}

.form-message:empty {
  opacity: 0;
}
</style>

7. Sticky/Fixed Elements

Fixed positioning can cause CLS if not done correctly.

Carrd Navigation/Header

If you have a sticky header:

<style>
/* Reserve space for sticky header */
body {
  padding-top: 80px; /* Height of your header */
}

#header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 80px;
  z-index: 1000;
}
</style>

Chat Widgets

Chat widgets are usually fixed position, but ensure they don't cause shifts:

<style>
/* Chat widget should use fixed positioning */
#chat-widget {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 60px;
  height: 60px;
  /* Does not affect layout flow */
}
</style>

Mobile-Specific CLS Issues

Mobile devices often have worse CLS scores.

Mobile Image Optimization

<style>
@media (max-width: 768px) {
  /* Ensure mobile images have explicit dimensions */
  .hero-image {
    width: 100%;
    aspect-ratio: 1 / 1; /* Square on mobile */
  }
}
</style>

Mobile Font Sizing

<style>
@media (max-width: 768px) {
  /* Prevent font size shifts on mobile */
  body {
    font-size: 16px; /* Explicit size */
    -webkit-text-size-adjust: 100%; /* Prevent iOS auto-sizing */
  }
}
</style>

Mobile Embed Handling

<style>
@media (max-width: 768px) {
  /* Mobile-specific embed containers */
  .embed-container {
    min-height: 300px; /* Smaller reserved space on mobile */
  }
}
</style>

Advanced Optimizations

Content Visibility API

For below-fold content, use content-visibility:

<style>
/* Skip rendering off-screen content */
.below-fold-section {
  content-visibility: auto;
  contain-intrinsic-size: 0 500px; /* Estimated height */
}
</style>

This tells the browser the estimated size before rendering.

Intersection Observer for Lazy Loading

Control when elements load:

<script>
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // Load content when visible
      const embed = entry.target;
      embed.style.minHeight = '0'; // Remove reserved space
      // Load actual content here
    }
  });
});

// Observe elements
document.querySelectorAll('.lazy-embed').forEach(el => observer.observe(el));
</script>

Testing Your CLS Improvements

Before and After Comparison

  1. Baseline: Test current CLS with PageSpeed Insights
  2. Note score: Record current CLS value
  3. Implement fixes: Apply optimizations from this guide
  4. Publish: Publish your Carrd site
  5. Clear cache: Hard reload (Ctrl+Shift+R)
  6. Retest: Run PageSpeed Insights again
  7. Compare: Verify CLS improvement

Testing Tools

Visual Regression Testing

Use Chrome DevTools to see shifts:

  1. F12 > More tools > Rendering
  2. Check Layout Shift Regions
  3. Reload page
  4. Blue rectangles show where shifts occur

Common Carrd CLS Issues and Fixes

Issue: Images Shifting on Load

Symptom: CLS 0.15-0.25, images identified in diagnostics

Fix:

<style>
/* Add aspect ratio to all images */
img {
  max-width: 100%;
  height: auto;
}

/* Specific image containers with known ratio */
.image-container {
  aspect-ratio: 16 / 9;
  width: 100%;
}
</style>

Expected improvement: CLS reduced to < 0.05

Issue: Font Loading Reflow

Symptom: CLS 0.08-0.12, text shifts when font loads

Fix:

<!-- Add font-display: swap to font URL -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">

<!-- Or preload fonts -->
<link rel="preload" as="font" href="FONT_URL.woff2" crossorigin>

Expected improvement: CLS reduced by 0.03-0.06

Issue: Embed Widget Shifting

Symptom: CLS 0.20+, third-party widget loads and pushes content

Fix:

<div style="min-height: 400px;">
  <!-- Widget code here -->
</div>

Expected improvement: CLS reduced to < 0.08

Issue: Mobile Layout Shifts

Symptom: Good CLS on desktop (0.05), poor on mobile (0.18)

Fix:

<style>
@media (max-width: 768px) {
  /* Set explicit heights for mobile */
  .hero-section {
    min-height: 400px;
  }

  /* Fixed mobile image dimensions */
  .mobile-image {
    aspect-ratio: 4 / 3;
    width: 100%;
  }
}
</style>

Expected improvement: Mobile CLS reduced to < 0.08

Issue: Form Success Message Shifts

Symptom: CLS spike when form success message appears

Fix:

<style>
/* Reserve space for form message */
.form-container {
  min-height: 500px; /* Include space for message */
}

.form-message {
  min-height: 60px;
  opacity: 0;
  transition: opacity 0.3s;
}

.form-message.visible {
  opacity: 1;
}
</style>

Expected improvement: Eliminates post-submit CLS

Monitoring CLS Over Time

Google Search Console

Track real-world CLS:

  1. Go to Google Search Console
  2. Navigate to Experience > Core Web Vitals
  3. Review CLS performance
  4. Identify pages with poor CLS
  5. Prioritize fixes for high-traffic pages

Real User Monitoring

Track CLS with GA4:

<script>
let cls = 0;
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
    }
  }
}).observe({type: 'layout-shift', buffered: true});

// Send to GA4 on page unload
window.addEventListener('beforeunload', function() {
  if (typeof gtag !== 'undefined') {
    gtag('event', 'CLS', {
      'value': Math.round(cls * 1000), // Convert to integer
      'event_category': 'Web Vitals',
      'transport_type': 'beacon'
    });
  }
});
</script>

Monthly CLS Audits

Establish routine checks:

  1. Monthly: Test key pages with PageSpeed Insights
  2. Review: CLS still in "good" range (< 0.1)
  3. Check: Any new embeds or images added?
  4. Fix: If CLS degraded, identify and fix cause
  5. Track: Document changes and improvements

Carrd CLS Best Practices

Design Phase

  • Plan image dimensions: Know sizes before upload
  • Limit embeds: Only essential third-party widgets
  • Use system fonts: When possible, avoid custom fonts
  • Fixed layouts: Predictable, stable layouts

Development Phase

  • Set explicit dimensions: All images and embeds
  • Reserve space: min-height for dynamic content
  • Test early: Check CLS before launch
  • Mobile first: Test mobile CLS during development

Maintenance Phase

  • Audit new embeds: Check CLS impact before adding
  • Monitor regularly: Monthly PageSpeed checks
  • Quick fixes: Address CLS issues immediately
  • Documentation: Note optimal embed heights for reuse

Next Steps

Additional Resources