Fixing shifting layouts: the most common causes
A shifting layout is the fault visitors feel most strongly and developers see least often — because on a fast machine with a full cache, nothing shifts. Six causes cover almost every case.
In short
- Six causes cover almost every case — images with no dimensions, late-loading fonts, embedded third-party content, notices shown afterwards, late-loading CSS, and dynamically inserted content.
- The value gets measured too favourably on your own machine: a fast connection, a full cache, a different screen size.
- The most effective single measure is giving every image and every embedded element fixed dimensions or an aspect ratio.
- A notice bar appearing after loading and pushing content down is the second most common cause — and the easiest to fix.
The six causes
1. Images with no dimensions
Without width and height the browser does not know how much space to reserve — the text slips as soon as the image arrives.
Fix: set both attributes and add height: auto in the CSS so the scaling is preserved.
2. Late-loading fonts
The text appears first in the fallback font and jumps on the switch, because the two run at different widths.
Fix: preload the font, use font-display: swap, and match the fallback font's metrics to the target font.
3. Embedded third-party content
Videos, maps and review widgets arrive with no known height and push everything down when they land.
Fix: provide a placeholder with a fixed aspect ratio for the content to load into.
4. Notices shown afterwards
A consent banner or a promotional bar appearing at the top after loading and pushing the whole page down.
Fix: reserve the space from the start, or overlay it rather than inserting it.
5. Late-loading CSS
If the stylesheet only takes effect after the first render, the page appears once unstyled and then styled.
Fix: deliver the rules needed for the visible area early — completely, not in parts.
6. Dynamically inserted content
A notice, a list or a section that JavaScript inserts above existing content after loading.
Fix: insert below the visible area, or reserve the space.
Worth knowing
Cause five is the most treacherous, because it hardly ever appears locally: on a fast connection the stylesheet arrives before the first render, and nothing shifts. On a slow connection it arrives afterwards — and the whole page renders twice.
Delivering part of the CSS early is not enough here: if a rule affecting the visible area is missing from it, that exact element shifts. Either complete for the visible area or not at all — half solutions are worse than none here.
Measuring properly
| Route | What it shows | Pitfall |
|---|---|---|
| Your own machine, developer tools | rough indications | too fast, cache full |
| A lab test in a checking tool | a reproducible value | one condition, not reality |
| Field data from real visitors | what actually happens | needs enough traffic |
| Mobile on a throttled connection | the most honest single test | has to be set deliberately |
One case that sticks: a page had a flawless value locally and a very poor one in the checking tool. The cause was a partially preloaded stylesheet — three rules for sections in the visible area were missing from it.
Locally that never showed, because the complete file arrived faster than the first render. Under throttling it arrived afterwards, and three sections shifted. The lesson: with shifting layouts the local impression is not counter-evidence but simply a different scenario — and usually the less realistic one.
The order for fixing
- Check every image.
widthandheightset,height: autoin the CSS. Usually half the problem. - Frame embedded third-party content. A placeholder with a fixed aspect ratio.
- Check what gets shown afterwards. Overlaying rather than inserting.
- Check font loading. Preload, match the fallback font.
- Check CSS delivery. Complete for the visible area.
- Measure again — throttled. And after each individual step, otherwise you do not know what worked.
Help me find and fix shifting layouts on our site. Details: - Measured value for layout shift: [value, tool, mobile or desktop] - Elements that shift according to the measurement: [list, if known] - Images with width/height attributes? [yes / no / partly] - How is CSS delivered? [external file / inlined up front / partly up front] - Embedded third-party content: [videos, maps, reviews, chat] - Does anything get shown after loading? [banner, notice, promotional bar] - How are fonts loaded? [details] Tasks: 1. Assign every shifting element to one of the six causes: images with no dimensions, late-loading fonts, embedded third-party content, notices shown afterwards, late-loading CSS, dynamically inserted content. 2. Name the concrete fix per cause with a code example. 3. If CSS is only partly delivered up front: explain why that can be worse than not at all, and what to check. 4. Give me an order by effect per unit of effort. 5. Tell me how I should measure after each step so I know what worked. Do not invent measurements.
In closing
Six causes, and the first — images with no dimensions — usually accounts for half. It is fixed in half an hour and works immediately.
The harder part is the measuring: check locally and you measure a scenario hardly any visitor experiences. Measure throttled, after each step individually — otherwise you fix three things and do not know which of them worked.
Common questions
Why does content shift while a page loads?
Usually from one of six causes: images with no dimensions, late-loading fonts with different metrics, embedded third-party content with no known height, notice bars shown afterwards, CSS taking effect late, and content inserted by JavaScript above the visible area.
What is the most effective single measure?
Giving every image width and height and adding height: auto in the CSS. The browser then reserves the right space from the start while the scaling is preserved. In practice this measure often accounts for half the problem.
Why is the value better locally than in a checking tool?
Because on your own machine the connection is fast and the cache is full: stylesheets, fonts and images arrive before the first render, and nothing shifts. Under realistic conditions they arrive afterwards — which is why measurement has to be throttled.
Can partially preloaded CSS do harm?
Yes. If a rule affecting a section in the visible area is missing from the preloaded part, that exact element shifts as soon as the complete stylesheet arrives. Either complete for the visible area or not at all — half solutions are worse than none here.
How do you fix shifting consent banners?
By overlaying them rather than inserting them — so they sit above the content without pushing it down. Alternatively the space can be reserved from the start. This cause is one of the most common and at the same time the easiest to fix.
Marketing that sets itself up
The Studio Engine beta is live. Claim your spot and help shape it from the start.
Join the beta →