wkhtmltopdf page size, margins, zoom and orientation in Chrome
The options that decide where your content lands on the paper (--page-size, -O, -T -R -B -L, --zoom, --print-media-type) all have a Chrome counterpart, but three of them behave differently enough to change a layout: the default margin, what happens to content wider than the page, and who wins when your CSS also sets a page size. Everything below was printed on Chromium 141 (Linux, 15 October 2026) and read back with pdfinfo and pdftotext -bbox; where something is untested it says so.
The options, side by side
| wkhtmltopdf | Playwright or Puppeteer page.pdf() | Plain Chrome command line |
|---|---|---|
--page-size A4, Letter, A5 | format: "A4" | No flag. Put @page { size: A4 } in the page's CSS. |
--page-width and --page-height | width and height (such as "210mm") | @page { size: 210mm 297mm } |
-O Landscape | landscape: true | @page { size: A4 landscape } |
-T 20mm -R 15mm -B 20mm -L 15mm | margin: { top: "20mm", right: "15mm", bottom: "20mm", left: "15mm" } | @page { margin: 20mm 15mm } |
--zoom 0.8 | scale: 0.8 (Playwright accepts 0.1 to 2) | No flag. Scale the content with CSS. |
--print-media-type | Not needed: page.pdf() uses print media. page.emulateMedia({ media: "screen" }) is the opposite switch. | Not needed: print media is the default. |
--javascript-delay 2000 | No option. Wait for the page to say it is ready, for example await page.waitForFunction(() => window.ready). | --virtual-time-budget=2000 is the nearest flag; not tested here. |
What we measured
1. The default margin is not the same everywhere
We printed an empty-margin test page four ways:
- Playwright
page.pdf()with no margin option: the text started at x = 0, right on the paper edge. If your wkhtmltopdf run used its default 10 mm margins, setmarginexplicitly or your content will touch the edge. Withmarginof 10 mm on each side the text started at about 28 pt (about 10 mm) from the left and, with a top margin, 28 pt from the top. - Chrome's own
--print-to-pdfcommand: a default margin of about 0.4 in is added, and the page was Letter (612 × 792 pt), not A4, even though the test file was plain HTML. For A4, set@page { size: A4 }in the CSS. - Playwright default paper is also Letter: without
formatthe file was 612 × 792 pt. Withformat: "A4"it was 595.92 × 842.88 pt.
2. Your CSS @page size can lose to the options
We gave a page @page { size: A5; margin: 0 } and called page.pdf({ format: "A4" }). The PDF was A4, and the A5-sized layout sat in the middle of it, about 88 pt in from the left. With preferCSSPageSize: true added, the PDF was A5 (420 × 594.96 pt) and the text started at x = 0. So if you want the stylesheet to decide, pass preferCSSPageSize: true (Puppeteer has the same option). If you want your code to decide, leave @page size out of the CSS.
await page.pdf({
path: "out.pdf",
format: "A4", // --page-size A4
landscape: false, // -O Portrait
margin: { top: "10mm", right: "10mm", bottom: "10mm", left: "10mm" },
scale: 1, // --zoom 1
printBackground: true // wkhtmltopdf printed backgrounds by default; Chrome does not
});
Backgrounds are the other quiet difference: wkhtmltopdf prints background colours and images unless you pass --no-background, while Chrome leaves them out unless printBackground: true (or -webkit-print-color-adjust: exact on the element). We did not re-measure that here; it is from the Playwright and Puppeteer documentation.
3. Content wider than the page
wkhtmltopdf's "smart shrinking" scales a wide page down to fit the paper. We built a 1,200 px wide row with a word at each end and printed it on A4:
- No margin: Chrome did scale the content down. The text was about two thirds of its normal size (an 8.7 pt line height instead of 13 pt) and the word at the right end ended at 600 pt on a 596 pt page, so it touched the edge.
- 10 mm left and right margins: the word at the right end was not in the PDF at all. The left word was there, and the right one had been cut off. No error or warning was shown.
scale: 0.5: the whole row fit, with the right-hand word ending at 450 pt.
So do not count on Chrome to shrink an oversized layout once you add margins. Either give the print layout a width that fits (for A4 with 10 mm margins, about 190 mm of content width) or set scale yourself. This disagrees with the note in our translator, which says "Chrome has no smart shrinking": the no-margin result above shows some shrinking exists, but it was not reliable once margins were set, and the translator's advice (set a width or use scale) is still the safe one.
Check your result in one line
pdfinfo out.pdf | grep "Page size" pdftotext -bbox out.pdf - | grep -c "The first line shows the real paper size. The second counts the words that reached the file; compare it with the count from your old wkhtmltopdf output (or from the text in the page) to catch anything that was cut off.
Do it without writing the options by hand
Paste your wkhtmltopdf command into the free command translator to get the Chrome command, a Playwright and Puppeteer snippet and the print CSS, with a list of options that have no equivalent. Related guides: headers and footers in Chrome and five page-break patterns.
Limits of this page
Tested: Chromium 141 (Playwright 1.56 build) on Linux, with test files we wrote and A4 and Letter paper. Not tested: Windows, macOS, other Chrome versions, Puppeteer itself,
--virtual-time-budget, and wkhtmltopdf's own output (its behaviour is described from its manual). Fonts change line heights, so the sizes quoted will differ with yours.