/ Image Optimisation Fixes / Image Dimensions

How to Fix Image Dimensions

Image dimension attributes (width and height) tell the browser how much space to reserve for the image before it loads. Without them, the page jumps as images render — that's CLS (Cumulative Layout Shift), one of the Core Web Vitals. Pages with missing image dimensions consistently score poorly on CLS. The fix is two extra attributes per image tag. Trivial work, significant ranking impact.

1. Audit missing dimensions

Step 1
Run the Image Optimisation audit
Lists every img tag without width and/or height attributes. Grouped by page so you can fix templates rather than individual instances.
Step 2
Quick scan in source
# Count img tags missing width or height
curl -s https://yoursite.com/ | \
  grep -oE '<img[^>]*>' | \
  grep -vE 'width="[^"]+"' | wc -l

curl -s https://yoursite.com/ | \
  grep -oE '<img[^>]*>' | \
  grep -vE 'height="[^"]+"' | wc -l

2. Add width and height attributes

<!-- Wrong: no dimensions, causes CLS -->
<img src="/hero.jpg" alt="Description">

<!-- Right: intrinsic dimensions -->
<img src="/hero.jpg" alt="Description" width="1200" height="675">

Use the natural (intrinsic) pixel dimensions of the source image. Not the displayed size. Browser uses these to calculate aspect ratio and reserve space.

Combine with CSS for responsive display

<img src="/hero.jpg" alt="..." width="1200" height="675"
     style="max-width: 100%; height: auto;">

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

width="1200" height="675" attribute gives the browser the aspect ratio (16:9). CSS max-width: 100%; height: auto lets the image scale down responsively while keeping that aspect ratio. Best of both worlds: no CLS, fully responsive.

3. Use aspect-ratio CSS for variable images

When dimensions aren't known at template render time (user-uploaded images, dynamic content), use CSS aspect-ratio to reserve space.

<!-- User-uploaded image, dimensions vary -->
<div class="user-image-wrapper">
  <img src="/uploads/abc123.jpg" alt="...">
</div>

<style>
.user-image-wrapper {
  aspect-ratio: 16 / 9;
  background: #f0f0f0;
}
.user-image-wrapper img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
</style>

Browser reserves a 16:9 box. Image loads inside that box, scaled to fit with object-fit. Even if the image's actual dimensions differ, the box stays at 16:9 — no layout shift.

4. Get dimensions automatically

WordPress: already does this

Built-in. wp_get_attachment_image() outputs width and height attributes automatically. If your theme uses bare img tags with hardcoded src, switch to the helper functions:

<!-- Bad: bare img -->
<img src="<?php echo $featured_image_url; ?>" alt="...">

<!-- Good: helper function -->
<?php echo wp_get_attachment_image($attachment_id, 'large'); ?>
<!-- Outputs: <img width="1200" height="675" src="..." alt="..." srcset="..." sizes="..." /> -->

Next.js Image component

import Image from 'next/image';
import heroImage from './hero.jpg';

<Image src={heroImage} alt="..." />
// width and height inferred from import metadata

Node build: Sharp metadata

const sharp = require('sharp');

async function getImageDimensions(filePath) {
  const meta = await sharp(filePath).metadata();
  return { width: meta.width, height: meta.height };
}

// At build time, pre-compute dimensions
const { width, height } = await getImageDimensions('./public/hero.jpg');
// Store in JSON, inject into templates

Server-side: probe-image-size (npm)

const probe = require('probe-image-size');
const result = await probe('https://example.com/image.jpg');
console.log(result.width, result.height);
// Downloads just enough bytes to read dimensions, then aborts

5. Handle responsive srcset

All srcset variants should have the same aspect ratio. width and height attributes on the img refer to one variant — typically the default src.

<img src="/hero-1200.jpg"
     srcset="/hero-400.jpg 400w,
             /hero-800.jpg 800w,
             /hero-1200.jpg 1200w,
             /hero-2400.jpg 2400w"
     sizes="(max-width: 800px) 100vw, 1200px"
     width="1200" height="675"
     alt="...">

Browser uses 1200x675 to compute aspect ratio (16:9). Whatever srcset variant ends up loading, the displayed size matches that aspect ratio. No CLS regardless of which variant is selected.

6. Common mistakes

Mistake 1: using CSS dimensions instead of attributes

<!-- BAD: CSS won't prevent CLS -->
<img src="/hero.jpg" style="width: 1200px; height: 675px">

<!-- GOOD: HTML attributes -->
<img src="/hero.jpg" width="1200" height="675">

CSS doesn't apply until the CSS file loads and parses. HTML attributes are available immediately when the parser hits the img tag.

Mistake 2: unit suffixes in attributes

<!-- BAD -->
<img width="1200px" height="675px">

<!-- GOOD -->
<img width="1200" height="675">

HTML width/height attributes take unitless integer pixel values. CSS uses px units.

Mistake 3: inconsistent aspect ratios across srcset

<!-- BAD: different aspect ratios for different sizes -->
<img src="/hero-1200.jpg"
     srcset="/hero-mobile-400x600.jpg 400w,
             /hero-1200x675.jpg 1200w"
     width="1200" height="675">
<!-- Mobile variant is 2:3 portrait, desktop is 16:9 landscape -->
<!-- Browser uses 16:9 for space reservation regardless -->
<!-- Mobile image then renders distorted or cropped -->

All srcset variants should share aspect ratio. If you need different crops at different viewports, use picture with art direction.

7. Art direction with picture

<picture>
  <source media="(max-width: 600px)"
          srcset="/hero-mobile-400x600.jpg"
          width="400" height="600">
  <source media="(min-width: 601px)"
          srcset="/hero-desktop-1200x675.jpg"
          width="1200" height="675">
  <img src="/hero-desktop-1200x675.jpg"
       alt="..."
       width="1200" height="675">
</picture>

Each source tag gets its own width/height. Browser picks source and reserves correct space.

8. Verify CLS improvement

Step 1
Lighthouse CLS metric
CLS under 0.1 is Good per Core Web Vitals. Pages with missing dimensions commonly score 0.2-0.5. After adding width/height, expect CLS to drop to 0.05 or below for most pages.
Step 2
Search Console field CLS
Search Console → Core Web Vitals. Real-user CLS data. Improvements visible 2-4 weeks after deployment as Google reprocesses field data.
💡 Audit and fix at the template level, not per image. The biggest CLS wins come from finding the 3-5 templates that emit dimensionless img tags and patching them. One template fix corrects thousands of pages at once.

🖼️ Re-run the Image Optimisation audit

Verify dimension findings and measure CLS improvement.

Run Image Audit →
Related Guides: Image Optimisation Fixes  ·  Fix Image CLS  ·  CLS Fixes  ·  Image Optimisation Guide
💬 Got a problem?