Cumulative Layout Shift (CLS) ruins user experience. Learn how to stop UI jitter using CSS containment and aspect-ratio properties for stable, faster pages.
Last month, our analytics dashboard saw a massive spike in CLS scores, and it wasn't because of bad code—it was because our dynamic image carousels were loading their assets after the initial paint. Watching the UI jump around while a user tries to click a button is the fastest way to lose trust. We needed a bulletproof way to reserve space for media before the browser even fetched the bytes.
Fixing Cumulative Layout Shift (CLS) isn't just about moving elements; it’s about giving the browser a map before it starts building the page. If you've been struggling with this, you're likely dealing with the "unknown height" problem.
When you inject an <img> tag or a video container without explicit dimensions, the browser has zero clue how much space that element will occupy. It renders the text around it, then, once the media hits the network, the browser realizes it needs space, pushes the text down, and—boom—you've got a layout shift.
We first tried hardcoding height and width attributes on every image tag. It worked, but it was brittle. Whenever we wanted to change the carousel’s layout for mobile, the hardcoded values forced us to use messy media queries just to override the attributes. It was a maintenance nightmare.
The aspect-ratio CSS property is a game-changer for responsive design. Instead of guessing heights or relying on fixed pixels, you define the relationship between width and height.
CSS#9CDCFE">color:#4EC9B0">.carousel-image { #9CDCFE">width: 100%; #9CDCFE">aspect-ratio: 16 / 9; #9CDCFE">object-fit: cover; }
By setting this, the browser reserves a 16:9 slot on the screen immediately. Even if the image takes 500ms to download, the space is already accounted for. You’ve effectively neutralized the shift. This is a foundational step in Cumulative Layout Shift: Advanced Strategies to Stop UI Jitter, and it’s the first thing I check when auditing a client's site.
Sometimes, you aren't just dealing with images; you’re dealing with complex widgets or ad slots where the content size is highly variable. This is where contain-intrinsic-size enters the room.
If you use content-visibility: auto to improve rendering performance (which you should), the browser essentially "skips" rendering off-screen elements. However, this can cause the scrollbar to jump as you move down the page because the browser doesn't know the element's height until it's rendered.
To fix this, combine content-visibility with contain-intrinsic-size:
CSS#9CDCFE">color:#4EC9B0">.dynamic-widget { #9CDCFE">content-visibility: auto; #9CDCFE">contain-intrinsic-size: 0 500px; #9CDCFE">color:#6A9955">/* Width, Height */ }
This tells the browser: "Assume this element is 500px tall while it's off-screen." It gives the browser a placeholder, preventing the scrollbar from jittering. When you combine these techniques, you're essentially building a robust defense for your Core Web Vitals.
I once spent about two days trying to debug a shift that only happened on slow 3G connections. It turned out that our font-loading strategy was causing a subtle layout change as the fallback font swapped to the web font. If you don't manage your font loading, all the aspect-ratio work in the world won't save your CLS score. I’ve written about how to Font Loading Strategy: Eliminate FOIT and Layout Shifts to ensure that the text doesn't move when the fonts finally arrive.
One thing I'm still figuring out is how to handle aspect-ratio when the image source is a user-uploaded file with unknown dimensions. Right now, we’re using a server-side helper to extract metadata and inject the aspect ratio into the style attribute, but it feels like a heavy lift.
Does aspect-ratio work on all browsers?
Yes, aspect-ratio has excellent support in all modern browsers (Chrome 88+, Firefox 89+, Safari 15+). For legacy support, you can use the classic "padding-bottom hack," though it's much harder to maintain.
Will contain-intrinsic-size fix all my layout shifts?
It fixes shifts caused by lazy-rendering or dynamic content insertion. It won't help if your CSS is inherently unstable (e.g., changing display: none to display: block on a large container).
Should I use this for everything?
Use aspect-ratio for media (images, videos, iframes). Use contain-intrinsic-size for large, complex components that are lazy-loaded. Don't over-engineer simple text blocks.
Ultimately, preventing layout instability is about discipline. You have to treat the page layout as a fixed structure that gets filled, rather than a fluid entity that grows as it pleases. Start with aspect-ratio for your images, and you'll see your metrics stabilize almost immediately.
Cumulative Layout Shift (CLS) ruins user experience. Learn how to stop UI jitter using CSS containment and aspect-ratio properties for a stable interface.
Read moreUse the Server-Timing API to correlate backend latency with Core Web Vitals. Stop guessing why your pages are slow and get full-stack observability today.