Short answer: wkhtmltopdf’s --margin-top, --margin-bottom, --margin-left, and --margin-right options apply to the entire PDF. They cannot begin at page two. For a single-file workaround, render a dedicated first-page wrapper, force a page break, and add padding inside the remaining content. If the second page must have a genuinely different physical page box, render the first page and body as separate PDFs with different margins, then merge them.
What wkhtmltopdf can and cannot change
The command-line margin options are document-wide settings. For example:
wkhtmltopdf --margin-top 10mm --margin-bottom 15mm --margin-left 15mm --margin-right 15mm input.html output.pdf
Those values are passed to the print system before pagination. There is no documented page-range form such as “use 40 mm on page one and 15 mm from page two.” Supplying --margin-top twice does not create a page-specific rule; the last value simply wins for the document.
CSS has paged-media constructs such as @page, @page :first, @page :left, and @page :right. They are valid CSS concepts, but wkhtmltopdf uses an older Qt/WebKit pagination pipeline. Its manual describes laying out a long page and cutting it into sheets, and support for page-specific margins is incomplete and build-dependent. Treat @page :first as an experiment, not a reliable production solution.
Recommended Free Tools
#1 Best Overall
Choose the right meaning of “different margin”
Before changing HTML, decide whether you need to move content or change the printable page area.
| Requirement | Best method | What changes | Important trade-off |
|---|---|---|---|
| More blank space above a cover or letterhead | One PDF, first-page wrapper plus padding on body pages | Content position inside the same page box | Physical margins remain global |
| Different left/right/top/bottom page box on page one | Two renders, then merge PDFs | Actual printable area per render | Post-processing may require checking links and outlines |
| Different margins on alternating pages | Separate rendering or a renderer with dependable paged-media support | True per-page geometry | Not dependable in stock wkhtmltopdf |
| Only a visual offset in one section | Inner wrapper, padding, or positioned element | Layout of that section | Can affect wrapping and page count |
Single-PDF workaround: first-page wrapper and forced break
This is the simplest approach when the first page is a cover, invoice header, or title sheet and the later pages merely need an inset. Set the CLI margins for the regular pages, keep the first page in its own block, and start the body explicitly on a new page.
Complete HTML example
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
@page { size: A4; }
html, body { margin: 0; padding: 0; }
body { font-family: Arial, sans-serif; font-size: 11pt; }
/* The CLI margins are the real document-wide page margins. */
.first-page {
page-break-after: always;
min-height: 240mm; /* tune for A4 and your CLI margins */
box-sizing: border-box;
}
.first-page h1 { margin: 0; padding-top: 8mm; }
.body-pages {
page-break-before: always;
padding-top: 20mm; /* simulated extra inset from page two onward */
}
.body-pages h2 { page-break-after: avoid; }
table, img { page-break-inside: avoid; }
</style>
</head>
<body>
<section class="first-page">
<h1>Quarterly report</h1>
<p>Prepared for the customer</p>
</section>
<main class="body-pages">
<h2>1. Summary</h2>
<p>The regular report starts here, with a 20 mm content inset.</p>
<h2>2. Detail</h2>
<p>Additional pages flow normally.</p>
</main>
</body>
</html>
Render it with the margins intended for the body pages:
wkhtmltopdf --page-size A4 --margin-top 12mm --margin-bottom 15mm --margin-left 15mm --margin-right 15mm report.html report.pdf
page-break-after on .first-page and page-break-before on .body-pages are deliberately redundant. Keeping the break on the boundary makes the intended transition clear and helps when one rule is affected by surrounding layout. The break must not be inside a floated parent. A reported wkhtmltopdf 0.12.x issue shows both properties being ignored when the parent is floated; removing the float allowed the break.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Why padding is safer than a first-child margin
Do not rely on margin-top on the first visible element of the body. wkhtmltopdf has a reported document-start bug in which that margin can be ignored. Put the inset on .body-pages with padding, or add an inner wrapper:
Rank #2
.body-pages { page-break-before: always; }
.body-pages-inner { padding-top: 20mm; }
Padding moves content while preserving the global page box. It can reduce the usable height, so headings, tables, and images may reflow onto additional pages. Tune min-height for the selected paper size and global margins rather than assuming a fixed pixel value.
When you need true physical margins: render and merge
If a cover must have a different printable area—not merely more blank space—use two wkhtmltopdf jobs. The first job receives the cover margins; the second receives the body margins. Then merge the resulting PDFs with a PDF tool available in your environment.
Render the two parts
wkhtmltopdf
--page-size A4
--margin-top 35mm --margin-bottom 20mm
--margin-left 25mm --margin-right 25mm
cover.html cover.pdf
wkhtmltopdf
--page-size A4
--margin-top 12mm --margin-bottom 15mm
--margin-left 15mm --margin-right 15mm
body.html body.pdf
Ensure both commands use the same paper size, orientation, zoom, DPI assumptions, fonts, and resource-loading options. A mismatch can produce a visibly different scale or page size after merging.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Merge and validate
Use your approved PDF merger to append body.pdf to cover.pdf. The exact command varies by platform and merger, so verify the tool’s syntax rather than copying an untested command. After merging, inspect:
- Page size and orientation of every page.
- Hyperlinks, bookmarks, and table-of-contents outlines.
- Font embedding and selectable text.
- Headers, footers, images, and page numbers at the join.
- Whether metadata or document-level outlines were retained.
The separate-render method is the dependable way to change the actual page box, but post-processing can affect links or outlines. Preserve source PDFs until the merged file has passed those checks.
Rank #3
Why @page :first often disappoints
CSS 2.2’s paged-media model allows a first-page rule such as:
@page { margin: 2cm; }
@page :first { margin-top: 10cm; }
That syntax expresses the requirement correctly in a standards-aware paged renderer. wkhtmltopdf’s WebKit engine does not consistently implement page selectors and page-box changes. A rule may be ignored, partially applied, or behave differently between binary builds. If you test it, test the exact wkhtmltopdf executable used in production and compare generated PDFs, but keep the wrapper or two-render method as your fallback.
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 →Clear out junk files and repair common Windows errorsFree Scan →Debugging page breaks and unexpected margins
The body starts on page one
- Confirm that
.first-pageis not inside a floated container. - Inspect the generated PDF for oversized content that overflows the first-page block.
- Keep both break rules on the non-floated boundary.
- Try a minimal HTML file to exclude invalid nesting or CSS collisions.
The second-page inset is missing
- Use padding on
.body-pagesor an inner wrapper, not only a first-child top margin. - Check for a later rule that sets
padding-top: 0. - Remember that CLI margins are still global; CSS padding is only a content offset.
The break is ignored after adding a layout wrapper
Floats are the most important known trigger. Remove the float from the parent of the break, replace it with normal flow, or move the first-page/body boundary outside the floated element. Also remove absolute positioning around the boundary while testing.
Content overlaps or an extra blank page appears
- Do not combine an oversized fixed height with large padding unless the box uses
box-sizing: border-box. - Reduce
min-heightuntil the cover fits inside one page. - Use only one intentional page boundary after the minimal test; duplicate breaks can expose blank pages when an element already begins on a new page.
- Check images and long tables, which can force overflow before the break is reached.
Margins differ between machines
wkhtmltopdf’s repository was archived on January 2, 2023, and pagination behavior varies by the exact 0.12.x binary, patched-Qt build, operating system, fonts, and command-line flags. Record the binary version, paper size, orientation, zoom, and installed fonts. Render a regression fixture in the same container or VM used in production.
Performance, reliability, and maintainability
Keep the single-render path deterministic
Use explicit paper size and margins, load the same fonts in every environment, and avoid layout that depends on viewport width. Give images fixed dimensions where possible. A small HTML fixture containing a cover, a forced break, a long paragraph, a table, and an image will reveal most pagination regressions.
Rank #4
- Includes Bonus CD
Prefer two renders for contractual geometry
Invoices, forms, and preprinted stationery often require a real printable-area change. Separate PDFs make that requirement explicit and easier to test than relying on undocumented CSS behavior. The cost is an extra render and a merge-validation step.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchExpect page-count changes
Increasing body padding reduces available height. Text wrapping, table splitting, and image placement can move content to later pages. Do not hard-code page numbers until the final binary, fonts, and assets are fixed.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your goal is simply to obtain clean page images or PDFs from a URL rather than maintain a wkhtmltopdf pipeline, ScreenshotNeo provides a GET-based screenshot API. It accepts cookie and consent banners before capture, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and lets you turn each cleanup step off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; each response identifies the result with X-Page-Verdict and X-Billed headers.
For PDF output, use its PDF options for paper size, margins, landscape mode, and page ranges. Other relevant controls include full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, clicks before capture, selector hiding, waits for a selector, delay or network idle, request/resource blocking, headers, cookies, user agent, Authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTL, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification.
One-call cURL example
curl -G "https://api.screenshotneo.com/v1/shot"
-d access_key=YOUR_API_KEY
--data-urlencode url=https://stripe.com
-o shot.webp
See the ScreenshotNeo documentation for PDF parameters, authentication, and the complete option list. The same endpoint also supports the parameter names used by other screenshot APIs, which can simplify migration.
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo’s free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. Sign up for the free plan to try it without a card.
Best Value
- Used Book in Good Condition
Frequently Asked Questions
Can I apply --margin-top only from page two?
No. wkhtmltopdf treats the CLI margin options as document-wide settings. Use a content wrapper or separate PDF renders.
Does page-break-before change the physical margin?
No. It controls pagination. Padding after the break moves content but does not change the page box.
Should I use @page :first in production?
Only after testing the exact wkhtmltopdf build. Support is inconsistent, so wrapper-based or two-render workflows are safer.
Free tools Windows power users keep installed
One-click scans. No signup required.
Why did my forced break disappear after adding a float?
A reported wkhtmltopdf issue shows page-break properties being ignored inside floated parents. Move the boundary outside the float or remove the float.
Quick 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.

