DEV Community

Nadim Chowdhury
Nadim Chowdhury

Posted on

Fixing Cumulative Layout Shift (CLS) with Modern CSS aspect-ratio and Math

Few things ruin user experience faster than Cumulative Layout Shift (CLS).

You are halfway through reading an article, an image finishes loading, and suddenly the entire paragraph jumps 300 pixels down the screen.

Even with modern frontend frameworks like Next.js, Remix, or SvelteKit, understanding how the browser calculates dimensions before assets load is critical for scoring a perfect 100 on Google Lighthouse.

Let’s review how aspect-ratio works, how to simplify non-standard aspect dimensions with Euclidean GCD, and how to eliminate layout jumps for good.


1. Why Layout Jumps Happen

When an HTML document renders:

  1. The browser parses the DOM and renders text immediately.
  2. An <img> tag without explicit aspect dimensions has an initial height of 0px.
  3. When the network response arrives with image data, the browser discovers the natural dimensions, re-calculates the layout tree, and violently pushes all surrounding elements downward.

2. The Native CSS aspect-ratio Property

Before 2021, developers used the dreaded "Padding-Bottom Hack" (padding-bottom: 56.25% for 16:9).

Today, modern CSS gives us the native aspect-ratio property:

.card-media {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
Enter fullscreen mode Exit fullscreen mode

When you set aspect-ratio: 16 / 9, the browser reserves the exact vertical bounding box before a single byte of image data has downloaded from the CDN. Layout shift is reduced to 0.00.


3. Simplifying Custom Ratios with the Euclidean Algorithm

What if your UI designer hands you custom media assets with non-standard pixel dimensions, like 1840px × 1150px or 2560px × 1080px?

To find the simplified ratio $W:H$, we compute the Greatest Common Divisor (GCD) using Euclid’s algorithm:

function getGcd(a: number, b: number): number {
  return b === 0 ? a : getGcd(b, a % b);
}

const width = 1840;
const height = 1150;
const divisor = getGcd(width, height); // 230

const ratioW = width / divisor;   // 8
const ratioH = height / divisor;  // 5
// Result: 8:5 aspect ratio (CSS: aspect-ratio: 8 / 5)
Enter fullscreen mode Exit fullscreen mode

4. Live Calculation & Screen Density Tools

If you are resizing video streams, responsive embeds, or responsive avatar grids, calculating scale factors, Megapixel densities, and PPI screen matrices by hand is tedious.

I built a free Responsive Aspect Ratio & Screen Density Studio on Omnikite.

It includes:

  • Live proportional resizing canvas with Euclidean ratio reduction.
  • Instant export for CSS aspect-ratio, Tailwind CSS classes (aspect-video, aspect-square, aspect-[16/9]), and SVG viewBox attributes.
  • Physical screen PPI (Pixels Per Inch) and Megapixel density calculators.

👉 Try the Aspect Ratio Calculator on Omnikite


Conclusion

Never ship an image or video container without reserving its spatial aspect ratio. A single line of CSS (aspect-ratio) is often the difference between a frustrating layout jitter and a buttery smooth 60fps experience.

Top comments (0)