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

Fix CLS Issues on Getsimplecms (Layout Shift)

Stabilize GetSimple CMS layouts by sizing images in PHP templates, preloading theme fonts, and constraining plugin-injected content.

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. GetSimple is an ultra-lightweight flat-file CMS, so CLS comes from theme template issues (unsized images, font loading) and plugin-injected content rather than complex server-side rendering.

GetSimple-Specific CLS Causes

  • Images without dimensions -- GetSimple's WYSIWYG editor (CKEditor) does not always save width/height on images in page content
  • Plugin-injected elements -- plugins that add cookie banners, notification bars, or sidebar widgets inject content after initial render
  • Theme font loading -- themes using Google Fonts via @import cause FOUT and text reflow
  • Gallery plugin rendering -- gallery plugins inject grid layouts that resize as images load
  • No responsive image handling -- uploaded images serve at original size without srcset or adaptive sizing

Fixes

1. Fix Images in Theme Templates

Add dimensions to images rendered by the theme:

<!-- In template.php -->
<?php if (get_page_meta_image()): ?>
  <div class="page-hero" style="aspect-ratio: 16/9; overflow: hidden;">
    <img
      src="<?php get_page_meta_image(); ?>"
      width="1200" height="675"
      alt="<?php get_page_clean_title(); ?>"
      style="width: 100%; height: 100%; object-fit: cover;"
    >
  </div>
<?php endif; ?>

For WYSIWYG content images, add CSS rules:

/* Fix unsized images in page content */
.content img {
  max-width: 100%;
  height: auto;
}

.content img:not([width]) {
  aspect-ratio: 16 / 9;
  width: 100%;
  object-fit: cover;
}

2. Constrain Plugin Output

Reserve space for plugin-injected content:

/* Cookie consent -- must overlay, not push */
.cookie-notice,
.gs-cookie-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 9999;
}

/* Sidebar plugin widgets */
.sidebar .plugin-widget {
  min-height: 100px;
  contain: layout;
}

/* Gallery plugin output */
.gs-gallery {
  min-height: 400px;
  contain: layout;
}

.gs-gallery img {
  aspect-ratio: 1 / 1;
  width: 100%;
  height: auto;
  object-fit: cover;
}

3. Fix Font Loading

Move font loading from CSS @import to HTML with preconnect:

<!-- In template.php <head> -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap" rel="stylesheet">
/* Fallback font metrics */
@font-face {
  font-family: 'Open Sans Fallback';
  src: local('Arial');
  size-adjust: 105%;
}

body { font-family: 'Open Sans', 'Open Sans Fallback', Arial, sans-serif; }

4. Handle Embedded Content

If pages contain iframes or embeds via the WYSIWYG editor:

/* Responsive iframe containment */
.content iframe {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
  border: 0;
}

/* Generic embed wrapper */
.embed-wrapper {
  position: relative;
  aspect-ratio: 16 / 9;
}

.embed-wrapper iframe {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}

Measuring CLS on GetSimple

  1. Chrome DevTools Performance tab -- record page load and filter for layout-shift entries
  2. PageSpeed Insights -- test your homepage and a few content pages
  3. Test with plugins disabled -- deactivate plugins one by one to find CLS sources
  4. Mobile testing -- GetSimple themes are often desktop-first with mobile CSS that introduces additional CLS

Analytics Script Impact

  • GetSimple has no built-in analytics -- all tracking is manually added to theme templates
  • Ensure any analytics scripts use async/defer and do not inject visible elements
  • Ad scripts should be placed in min-height containers
  • Avoid heatmap tools that inject feedback buttons without fixed positioning