How to overlay a design mockup on a live page
Comparing a design to a build by eye is unreliable. The eye tolerates a few pixels of drift, especially on large type and generous spacing. Overlaying the design directly on the rendered page removes that tolerance: misalignment becomes visible immediately, and you can measure it rather than argue about it.
Get the design at the right scale first
Three settings decide whether the overlay is honest:
- Viewport width. Match the frame width the design was made at. A 1440px design viewed in a 1280px window is scaled, and every measurement is wrong.
- Device pixel ratio. On a Retina screen the page renders at 2x. If your export is 1x, the overlay will look soft and edges will not line up crisply.
- Browser zoom. Set it to 100% and leave it there.
Also account for the scrollbar, which changes the usable width. Hiding it with CSS changes layout on most sites; measure with it present instead.
The console method
Paste this into DevTools on the live page, replacing the URL with your exported image. It creates a full-screen, click-through overlay you can fade with a keyboard shortcut:
const img = document.createElement('img');
img.src = 'https://example.com/mockup.png';
Object.assign(img.style, {
position: 'fixed', inset: '0', width: '100%', height: 'auto',
opacity: '0.5', zIndex: '2147483647', pointerEvents: 'none'
});
document.body.appendChild(img);
document.addEventListener('keydown', e => {
if (e.key === ']') img.style.opacity = Math.min(1, +img.style.opacity + 0.1);
if (e.key === '[') img.style.opacity = Math.max(0, +img.style.opacity - 0.1);
});pointerEvents: none is what makes this usable: the page stays interactive underneath, so you can open menus and check states rather than only the default view. Press ] and [ to fade between the design and the build.
Limits: this positions from the top-left and does not remember anything. Reload and it is gone, and you cannot nudge the image by a pixel to test a theory.
Difference mode, and when it lies
Fading between two images shows offset; blending them with a difference mode shows displacement as colour fringing, which is easier to spot on dense layouts. Both are useful and both mislead in the same way: if the overlay is 1px off from the start, every element looks wrong. Anchor on something you know is correct — the logo edge or a container border — before you judge anything else.
What usually causes the mismatch
- Font rendering. Different platforms hint and space text differently. Line breaks shift even with identical CSS.
- Missing font. A fallback font changes every measurement downstream.
- Scrollbar and viewport. A 15px scrollbar moves centred content by 7–8px.
- Sub-pixel rounding. Percentage widths land on fractional pixels and round differently per engine.
- Images without fixed dimensions. Content shifts as they load.
Only the first two are worth fixing. Chasing sub-pixel rounding is how an afternoon disappears.
Doing it repeatedly
The console method is right for a one-off. If you compare the same product every sprint, you want the mockup to persist per domain, remember its offset, and support more than one layer so you can stack states. That is what PixelLayer Pro does, with six layers free and keyboard nudging to the pixel. Compare the field before choosing: the PixelLayer vs PerfectPixel page covers the trade-offs honestly.
PixelLayer Pro
Six free layers, per-domain memory, pixel nudging and a difference mode.
See PixelLayer Pro →Common questions
- Why does my overlay never line up exactly?
- Usually a scale mismatch: the design frame width, the window width and the browser zoom do not agree, or the export is 1x on a 2x display. Fix those three before moving the image by a single pixel.
- Can I overlay a PDF or a Figma file directly?
- Not in the browser. Export a PNG at the frame's exact pixel dimensions first; PDFs and Figma files are not rendered by an image overlay.
- Does the overlay affect the site or other users?
- No. It is a local element in your own browser tab. Nothing is uploaded and nobody else sees it.