Free tools Windows power users keep installed
One-click scans. No signup required.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Overlapping images in an HTML-to-PDF file are usually caused by a difference between screen and print CSS, mismatched page geometry, or content crossing a page boundary. Identify the renderer and version, render with the intended media type, make CSS @page settings agree with the PDF options, then test page-break rules around the affected image. Change one variable at a time so you know which adjustment fixed the output.
Why images overlap in a PDF when the HTML looks correct
A browser view is not the same layout that a PDF engine paginates. The converter may select print media, apply a different viewport, scale the page to a paper size, or split a containing block at a page boundary. An image can therefore have a different width, height, or position in the PDF than it has on screen.
Print CSS can change the layout
Puppeteer’s Page.pdf() generates a PDF with the print CSS media type by default. A rule inside @media print can hide an element, change its display mode, alter margins, or resize an image even though the screen rendering is correct. To deliberately use screen styles, Puppeteer documents calling page.emulateMediaType('screen') before page.pdf(). Compare both modes rather than assuming the screen preview represents the PDF.
CSS page geometry and PDF options may disagree
Paper size, orientation, margins, and scale are separate controls. CSS @page can specify one geometry while the API call requests another. Puppeteer’s PDF options include dimensions, margins, scale, and preferCSSPageSize. Its default for preferCSSPageSize is false, so content is normally fitted to the requested paper size unless CSS page sizing is given priority. That fitting can change the dimensions of an image’s containing block.
#1 Best Overall
Pagination can split an image container
If the overlap starts exactly at the top or bottom of a page, investigate pagination before changing image dimensions. A parent element may be split while the image itself is treated as an indivisible or positioned child. WeasyPrint documents support for break-before, break-after, and break-inside, along with the older page-break-* aliases. Other engines support different subsets or interpret them differently.
Image sizing and positioning are hypotheses, not universal diagnoses
Intrinsic image dimensions, an unconstrained height, absolutely positioned descendants, lazy-loaded content, and late-running scripts can all be worth testing in the actual document. None is a guaranteed explanation for every renderer. Inspect the computed styles and the parent’s box in the failing PDF path before applying a global rule.
A renderer-independent diagnostic sequence
- Record the renderer and exact version. Write down whether the job uses Puppeteer/Chromium, WeasyPrint, Prince, a hosted service, or another engine. Pagination and CSS support vary by implementation and version.
- Make a reduced reproduction. Keep one problematic image, its immediate parent, the relevant print rules, and the same fonts and assets. Remove unrelated scripts and sections until the overlap either disappears or can be reproduced in a small file.
- Compare screen and print media. Capture computed
display,position,width,height,margin, andoverflowfor the image and every positioned ancestor under both media types. - Write down page geometry. Confirm CSS
@pagesize and margins, API paper size and margins, orientation, device scale, and PDF scale. Do not change all of them at once. - Constrain the image and its containing block. Give the image a predictable maximum width, an automatic height that preserves its aspect ratio, and a parent with a normal flow layout. Remove absolute positioning temporarily to test whether it is involved.
- Test the page boundary. Add a temporary
break-inside: avoidto the image wrapper, or force a break before it. If the overlap moves or disappears, the defect is pagination-related rather than a simple width calculation. - Change one variable and render again. Keep the same HTML, assets, renderer version, media type, and page geometry for each comparison. Save the PDF and a short note describing the single change.
CSS baseline for predictable image layout
Use a baseline like this as a diagnostic, not as a universal cure. Apply it in the print stylesheet and then relax individual declarations after the output is stable.
@page {
size: A4 portrait;
margin: 16mm;
}
@media print {
.image-block {
display: block;
position: relative;
width: 100%;
break-inside: avoid;
page-break-inside: avoid;
}
.image-block img {
display: block;
max-width: 100%;
width: auto;
height: auto;
position: static;
}
}
max-width: 100% prevents an image from exceeding the content box, while height: auto preserves its intrinsic ratio. The two page-break declarations provide a modern property and a legacy alias; the renderer still determines how reliably either is honored.
Puppeteer: control media, geometry, and breaks explicitly
Install Puppeteer in the project that performs the conversion, then render the same URL or local file used in production. The example below first chooses screen media (remove that line when print CSS is the intended design), gives the call explicit margins and format, and lets CSS page size take priority.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 900, deviceScaleFactor: 1 });
await page.goto('https://example.com/report', { waitUntil: 'networkidle0' });
// Use screen rules for this diagnostic. Omit to use print rules (the default).
await page.emulateMediaType('screen');
// Wait for images that are inserted or decoded after navigation.
await page.waitForFunction(() =>
Array.from(document.images).every(img => img.complete)
);
await page.pdf({
path: 'report.pdf',
format: 'A4',
printBackground: true,
margin: { top: '16mm', right: '16mm', bottom: '16mm', left: '16mm' },
scale: 1,
preferCSSPageSize: true
});
} finally {
await browser.close();
}
})();
Run the file once with emulateMediaType('screen') and once without it. If only one version overlaps, inspect the corresponding media rules. If both versions overlap, compare the image’s box before and after page.pdf(), then test page geometry and breaks.
When a page uses lazy loading, scrolling or an application-specific readiness signal may be necessary before PDF generation. Use a selector wait, a deterministic delay, or a network-idle condition only when it reflects the page’s real loading behavior; an arbitrary long delay can hide a race without fixing it.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →WeasyPrint: let @page describe the document
WeasyPrint’s documented model uses CSS @page for page size and margins. Keep those values in the stylesheet and verify that the command or library invocation is not applying a second, conflicting geometry. A minimal command-line conversion is:
weasyprint report.html report.pdf
For a reproducible test, place the image wrapper and its print rules in report.html, render it with the same WeasyPrint version used by the service, and inspect whether the overlap begins at a page break. Apply break-before, break-after, or break-inside to the wrapper, then test the legacy page-break-* aliases if the engine or existing stylesheet relies on them. Do not assume a rule supported by WeasyPrint has identical effects in Chromium.
Page-break patterns to test
Keep a figure and caption together
.figure {
break-inside: avoid;
page-break-inside: avoid;
}
This is appropriate when the image and caption must remain one unit. It may move the entire block to the next page, increasing white space.
Start a large image on a new page
.large-figure {
break-before: page;
page-break-before: always;
}
Use this as a diagnostic or for deliberately full-page artwork. Remove it if it merely masks an incorrect height or margin.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteAllow a controlled break after the figure
.figure {
break-after: avoid;
page-break-after: avoid;
}
Support and precedence differ among engines, so verify the generated PDF rather than relying on the stylesheet alone.
Common symptoms, causes to test, and fixes
| Symptom | What to inspect | Targeted test |
|---|---|---|
| Only the PDF overlaps; the browser view is correct | Print media rules and computed styles under print |
Render with screen media, then compare the print stylesheet one rule at a time |
| Every image is uniformly too large or too small | @page size, API format, margins, and scale |
Set one paper size and margin source; in Puppeteer test preferCSSPageSize: true |
| Overlap begins at a page top or bottom | Wrapper height and page-break behavior | Apply break-inside: avoid to the wrapper and render again |
| The image covers text or other elements | Absolute/fixed positioning and stacking context | Temporarily set the image and ancestors to normal flow with position: static |
| Only images loaded late are affected | Navigation readiness, lazy loading, and image completion | Wait for the page’s real readiness condition and verify img.complete |
| One engine works and another fails | Engine-specific paged-media and break support | Keep the same HTML and compare documented support; do not transfer a fix blindly |
Reliability, performance, and operating notes
- Use deterministic inputs. Pin the renderer version, fonts, image URLs, and CSS. A font fallback can change line wrapping and push an image onto a different page.
- Wait for assets deliberately. Network-idle is useful for pages that finish loading predictably; a selector or application readiness flag is safer when analytics or long polling keeps the network busy.
- Keep geometry in one place. Either make CSS
@pageauthoritative or make API options authoritative, then document that decision for future changes. - Compare PDFs visually and structurally. Save a known-good file, render the same input after each change, and check page count, image bounds, and the first page where positions diverge.
- Do not treat a renderer swap as proof of a fix. A different engine can support different CSS, but it may also change line wrapping, fonts, and pagination. Evaluate compatibility with the document you actually generate.
When evaluating another HTML-to-PDF renderer
Prince describes its product as converting HTML and XML to PDF using CSS. It may be relevant for print-focused workflows, but the available documentation does not establish that it fixes a particular overlapping-image defect. Compare engines on the features your document needs rather than on an assumed ranking.
| Comparison axis | Questions to answer |
|---|---|
| CSS and paged media | Does the engine support the selectors, @page rules, generated content, and break properties in your stylesheet? |
| Geometry control | Can you set paper size, margins, orientation, scale, and page ranges without conflicting defaults? |
| Existing HTML compatibility | Does your current layout, JavaScript, font loading, and image pipeline render without a rewrite? |
| Operations | Can you pin versions, run it in your deployment environment, and capture useful logs for failed jobs? |
| Licensing and cost | What license or service charge applies to your volume and distribution model? |
Or skip the browser setup
ScreenshotNeo can capture a clean rendering of a URL before you troubleshoot the PDF pipeline. It accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
Use the one-call API to obtain a clean reference image of the page you are converting. The complete parameter reference is in the ScreenshotNeo documentation.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The service supports full-page capture with lazy images loaded, a single element selected by CSS, dark mode, 12 device presets or any viewport, retina scale, PDF paper size, margins, landscape mode and page ranges, HTML/CSS-to-image, custom CSS and JavaScript, clicking an element before capture, hiding selectors, waits for a selector, delay or network idle, blocking ads, trackers, requests or resource types, custom headers, cookies, user agent and Authorization, timezone and geolocation, transparent backgrounds, image resizing, a user-selected cache TTL, signed links for public image tags, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, an OpenAPI specification, and compatibility with parameter names used by other screenshot APIs.
Rank #4
Plans are Free: 1,000 shots per month with no card; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; and Business: $249 for 1,000,000. Yearly billing provides two months free, and every feature is included on every plan. Create a free ScreenshotNeo account to get 1,000 screenshots a month without a card.
FAQ
Should I always use screen media for PDF generation?
No. Use print media when your print stylesheet is intentional. Screen media is a diagnostic option when you need to confirm whether print-only rules cause the overlap.
Can break-inside: avoid guarantee that an image stays on one page?
No. The property is a request interpreted by the renderer, and support varies. Verify the actual PDF and test the legacy alias when appropriate.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Does changing the renderer prove the original CSS was wrong?
No. Different engines implement paged media differently. A renderer change is an evaluation choice that must be checked against your HTML, CSS, fonts, and operational requirements.
Frequently Asked Questions
Should I always use screen media for PDF generation?
No. Use print media when your print stylesheet is intentional. Screen media is a diagnostic option when you need to confirm whether print-only rules cause the overlap.
Can break-inside: avoid guarantee that an image stays on one page?
No. The property is a request interpreted by the renderer, and support varies. Verify the actual PDF and test the legacy alias when appropriate.
Does changing the renderer prove the original CSS was wrong?
No. Different engines implement paged media differently. A renderer change is an evaluation choice that must be checked against your HTML, CSS, fonts, and operational requirements.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsQuick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

