General Guide: See Global CLS Guide for universal concepts and fixes.
What is CLS?
Cumulative Layout Shift measures visual stability. Google recommends CLS under 0.1. Voog generates CLS from content area editable regions rendering after the page frame, images in Liquid templates without dimensions, multi-language switcher loading, and web font loading in custom themes.
Voog-Specific CLS Causes
- Content area rendering -- Voog's content areas inject editable markup that can shift surrounding elements, especially when the editing interface initializes
- Images without dimensions -- images output via Liquid tags render without explicit
width/heightunless added manually - Language switcher injection -- the multi-language navigation bar loads and renders after the main content on multi-language sites
- Blog listing variability -- blog post cards with optional images and variable excerpt lengths create inconsistent heights
- Google Fonts FOUT -- custom fonts selected in the theme design settings load asynchronously
Fixes
1. Size Images in Liquid Templates
{% comment %} Hero image with dimensions {% endcomment %}
{% if page.image %}
<div class="hero-wrapper" style="aspect-ratio: 16/9; overflow: hidden; background: #f0f0f0;">
<img
src="{{ page.image | image_url: width: 1200 }}"
width="1200" height="675"
alt="{{ page.title }}"
style="width: 100%; height: 100%; object-fit: cover;"
>
</div>
{% endif %}
{% comment %} Blog listing images {% endcomment %}
{% for article in blog.articles limit: 6 %}
<div class="article-card" style="min-height: 280px; contain: layout;">
{% if article.image %}
<div style="aspect-ratio: 16/9; overflow: hidden; background: #f0f0f0;">
<img
src="{{ article.image | image_url: width: 400 }}"
width="400" height="225"
alt="{{ article.title }}"
loading="lazy"
style="width: 100%; height: 100%; object-fit: cover;"
>
</div>
{% else %}
<div style="aspect-ratio: 16/9; background: #f0f0f0;"></div>
{% endif %}
<h3><a href="{{ article.url }}">{{ article.title }}</a></h3>
</div>
{% endfor %}
2. Reserve Space for Content Areas
/* Voog content area containment */
.content-area {
min-height: 200px;
contain: layout;
}
/* Sidebar content area */
.sidebar .content-area {
min-height: 150px;
}
/* Footer content area */
.footer .content-area {
min-height: 100px;
}
For content body images:
/* Fix unsized images in editable content */
.content-area img {
max-width: 100%;
height: auto;
}
.content-area img:not([width]) {
aspect-ratio: 16 / 9;
width: 100%;
object-fit: cover;
}
/* Embedded iframes */
.content-area iframe {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
border: 0;
}
3. Stabilize Language Switcher
/* Pre-reserve space for the language switcher */
.language-switcher {
min-height: 40px;
min-width: 100px;
contain: layout;
}
{% comment %} Render language switcher inline in the header {% endcomment %}
<header style="display: flex; align-items: center; height: 64px;">
<nav class="main-nav">{{ site.navigation }}</nav>
{% if site.languages.size > 1 %}
<nav class="language-switcher" style="min-width: 80px;">
{% for lang in site.languages %}
<a href="{{ page.url | localize: lang.code }}">{{ lang.code | upcase }}</a>
{% endfor %}
</nav>
{% endif %}
</header>
4. Fix Blog Listing Consistency
/* Consistent blog card layout */
.article-card {
min-height: 280px;
contain: layout;
}
.article-card .excerpt {
max-height: 4.5em;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
5. Preload Theme Fonts
{% comment %} In your layout <head> {% endcomment %}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
{% if theme.font_file %}
<link rel="preload" href="{{ theme.font_file }}" as="font" type="font/woff2" crossorigin>
{% endif %}
@font-face {
font-family: 'ThemeFont';
src: url('fonts/theme.woff2') format('woff2');
font-display: swap;
size-adjust: 103%;
}
Measuring CLS on Voog
- Chrome DevTools Performance tab -- record page load and filter for layout-shift entries
- Test multi-language pages -- language switcher loading is a unique CLS source on Voog
- Test blog listings -- pages with variable article cards have the highest CLS risk
- Compare published vs. editor -- the editing interface adds its own CLS that does not affect published pages
Analytics Script Impact
- Add analytics via Liquid layout templates or Voog's code injection, not inline in content areas
- Ensure scripts use
async/deferand do not inject visible DOM elements - Cookie consent implementations should use
position: fixedoverlay - Voog's built-in analytics are server-side and cause no CLS