HTML and CSS code snippet showing how to declare width, height, and aspect-ratio on an imageDetailed guide

Image Dimensions Implementation Guide: Code, Automation, and Complex Cases

View contents

Image Dimensions Implementation Guide: Code, Automation, and Complex Cases

Introduction

This guide covers how to declare image dimensions consistently across HTML, CSS, and modern frameworks, how to automate dimension extraction from a CMS, and how to handle responsive layouts without sacrificing the space reservation that prevents Cumulative Layout Shift (CLS). The UXR SEO Analyzer reports every <img> without declared width/height as a Core Web Vitals finding.

If you need the conceptual background first, see Image Dimensions Explained.

Base Pattern: HTML Attributes

<img
  src="/img/product.jpg"
  alt="Gray running shoes with orange sole"
  width="800"
  height="600"
  loading="lazy">

The browser uses width and height to compute the intrinsic aspect ratio and reserves that space even if CSS later scales the image to a different container width—as long as the CSS preserves the proportion.

Responsive Pattern: CSS That Preserves Proportion

img {
  max-width: 100%;
  height: auto;
}

This classic rule makes the image fit the container's width while the browser calculates height automatically from the HTML's width/height attributes—preserving the space reservation without fixing a rigid pixel size.

Using CSS aspect-ratio Directly

.hero-image {
  aspect-ratio: 16 / 9;
  width: 100%;
  object-fit: cover;
}

aspect-ratio is especially useful when the image is a CSS-generated background or when the container's size doesn't match the file's original dimensions.

Automation in Frameworks

Next.js

The next/image component requires width/height (or fill with a sized container) and automatically computes the aspect-ratio placeholder, failing the build if they're missing.

Nuxt / Vue

@nuxt/image offers the same validation through the <NuxtImg> component, generating a correctly sized placeholder during SSR.

Headless CMS (Contentful, Sanity, Strapi)

Most headless CMSs return the asset's original dimensions in the API response. Extract and persist those values alongside the URL at query time, instead of assuming a fixed size.

const { url, width, height } = image.fields.file.details.image;
// <img src={url} width={width} height={height} alt="..." />

Validation and Testing

  1. Run Lighthouse and check the CLS section of the Core Web Vitals report.
  2. Use Chrome DevTools (Performance panel, "Experience" section) to visualize elements causing layout shift.
  3. Add a lint rule (for example, eslint-plugin-jsx-a11y with image rules) that fails the build when width/height is missing.

Common Mistakes

MistakeConsequenceFix
Using width: 100%; height: 100% in CSS without aspect-ratioThe browser can't compute height and collapses the spaceAdd aspect-ratio or keep height: auto
Declaring incorrect dimensions (different from the real file)The computed aspect ratio mismatches, distorting or cropping the imageSync dimensions with the actual file on every upload
Omitting dimensions on JavaScript-injected imagesLayout shift happens after hydration, invisible in static testsReserve the container with CSS before injecting the image

Complex Case: Galleries and Carousels

Gallery components typically swap the visible image via JavaScript when navigating between slides. If the new <img> element doesn't include width/height or the container doesn't have a fixed CSS aspect-ratio, every slide change can introduce an additional layout shift, even if the page's initial load was well optimized.

.carousel-slide {
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

.carousel-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

By fixing the aspect-ratio on the slide's container rather than on the individual image, you guarantee the reserved space doesn't change no matter which image loads inside it.

Complex Case: Art-Directed Images With Dynamic Cropping

When you use <picture> with different crops per breakpoint (art direction), each <source> can have a different aspect ratio than the fallback image. In that case, declare width/height on the final <img> element based on the most likely crop (usually the desktop one), and use CSS aspect-ratio per breakpoint for cases where the crop changes significantly:

<picture>
  <source media="(max-width: 600px)" srcset="/hero-mobile.jpg">
  <source media="(min-width: 601px)" srcset="/hero-desktop.jpg">
  <img src="/hero-desktop.jpg" width="1200" height="600" alt="Image description">
</picture>
@media (max-width: 600px) {
  picture img { aspect-ratio: 4 / 5; }
}

Measuring the Real Impact in Production

Beyond Lighthouse (which measures under lab conditions), it's worth monitoring CLS with field data using the PerformanceObserver API with the layout-shift type, or by integrating a library like Google's web-vitals, to confirm real users aren't experiencing shifts the lab environment didn't capture (for example, on connections slower than simulated ones). Field data also surfaces device-specific issues lab testing tends to miss, such as older phones taking noticeably longer to decode large images, which widens the window during which an unreserved image space can shift.

import { onCLS } from 'web-vitals';

onCLS((metric) => {
  console.log('This user\'s real CLS:', metric.value);
  // send to your analytics system
});

Implementation Checklist

  1. Every image in the initial markup has width/height or an equivalent aspect-ratio.
  2. Components that dynamically swap images (carousels, lightboxes) preserve the container's space reservation.
  3. Responsive CSS rules (max-width: 100%; height: auto) don't break the computed proportion.
  4. Field CLS (not just lab CLS) is monitored with web-vitals or an equivalent tool.

Complex Case: User-Generated Images With Unknown Dimensions

On platforms where users upload their own images (marketplaces, social networks, forums), you don't always know the file's dimensions ahead of time. The most robust solution is to read the actual dimensions at upload time—either server-side with a library like sharp (Node.js) or Pillow (Python)—and persist them alongside the file reference, instead of trying to guess them or using a fixed value that will likely distort some images.

import sharp from 'sharp';

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

// Store { width, height } in the database alongside the file record

Dominant Color Placeholder While Loading

Reserving the correct space solves the layout shift, but you can further improve perceived experience by showing a background color or a blurred placeholder (a technique known as LQIP, Low Quality Image Placeholder) while the high-resolution image finishes loading inside the already-reserved space:

.image-container {
  aspect-ratio: 16 / 9;
  background-color: #e2e2e2; /* approximate dominant color */
}

This technique doesn't affect CLS (the space was already reserved) but it reduces the "blank screen" feeling during load.

Auditing an Entire Site for Missing Dimensions

For a large existing site, checking every template manually isn't practical. A lightweight crawler script can flag every rendered <img> missing both the width/height attributes and any CSS aspect-ratio rule targeting it, then group the results by template or component so engineering can fix the shared source once instead of patching individual pages. Pair this audit with the CLS section of a site-wide Lighthouse CI run so regressions get caught in pull requests rather than after deployment.


References

  1. web.dev - Optimize Cumulative Layout Shift
  2. web.dev - Cumulative Layout Shift (CLS)
  3. Chrome Developers - Layout shift culprits
  4. Chrome Developers - Chrome UX Report metrics

Related articles

Related version

Introduction

Image Dimensions: Why Explicit Width and Height Prevent Layout Shifts

Declaring width and height on every image lets the browser reserve space before download, preventing layout shifts that hurt CLS.

Category hub

Hub

Images Seo Hub

Images are critical to user engagement—but they can also be your website's biggest performance bottleneck

In the same category

Detailed guide

Cls Optimization Guide

Cumulative Layout Shift (CLS) measures the visual stability of your page

Detailed guide

Responsive Images Implementation Guide

Responsive images are one of the most impactful performance optimizations you can implement

Detailed guide

Oversized Images Optimization Guide

Images account for approximately 50% of the average webpage's total bytes

Other topics

Hub

Performance Seo Hub

Performance is a critical ranking factor and directly impacts user experience