2

I'm generating a PDF from a responsive web page (mobile version) using a headless Chrome instance and the Chrome DevTools Protocol (CDP) in Java. The goal is to produce a single-page PDF that reflects exactly what the user would see on a mobile screen.

My Setup:

  1. I launch headless Chrome in the terminal.
  2. I connect to it using the webSocketDebuggerUrl.
  3. I execute the following CDP commands in this order (all synchronously):
// Step 1: Enable required domains
send("Page.enable");
send("Runtime.enable");
send("Log.enable");

// Step 2: Set mobile viewport
send("Emulation.setDeviceMetricsOverride", {
  width: 360,
  height: 640,
  deviceScaleFactor: 1,
  mobile: true
});

// Step 3: Set media to screen
send("Emulation.setEmulatedMedia", {
  media: "screen"
});

// Step 4: Navigate to the URL
send("Page.navigate", {
  url: "https://arunac97.github.io/samplesite.com/newcanvas.html"
});

// Step 5: Wait for the page to load (handled properly in code)

// Step 6: Get layout metrics
JSONObject layout = send("Page.getLayoutMetrics");
JSONObject cssContentSize = layout.getJSONObject("cssContentSize");
float contentWidth = cssContentSize.getFloat("width");
float contentHeight = cssContentSize.getFloat("height");

// Step 7: Print to PDF
send("Page.printToPDF", {
  paperWidth: contentWidth / 96, (converting pixel to inch - 96 dpi)
  paperHeight: contentHeight / 96,
  marginTop: 0,
  marginBottom: 0,
  marginLeft: 0,
  marginRight: 0,
  scale: 1,
  printBackground: true
});

Problem: The PDF is generated correctly, but it includes a large blank space at the bottom—about 30% of the page height—which shouldn't be there.

  1. I'm using Page.getLayoutMetrics to determine the real content size and feeding those exact values (converted to inches) into Page.printToPDF.
  2. I'm drawing a element using JavaScript after the page loads. The canvas is sized to exactly match the full scrollable width and height of the page and is positioned on top of all content.

If I use a custom paperWidth and paperHeight in printToPDF that doesn't exactly match the page's real dimensions, Chrome seems to re-render the page with those new dimensions during PDF generation. This causes the canvas to become misaligned or appear at the wrong place, since it was drawn based on the original page size.

That's why I'm using the exact width and height from Page.getLayoutMetrics to avoid this rendering issue and preserve the canvas position.

Questions: What causes this extra space to be appended to the bottom of the generated PDF?

  1. Is there a better way to determine the exact printable area without causing canvas misalignment?
  2. Is there any known workaround to force Page.printToPDF to honor only the actual visible content?
  3. Any help or insight would be deeply appreciated.

This is a test website I hosted on GitHub Pages to reproduce and test these cases: https://arunac97.github.io/samplesite.com/newcanvas.html


GitHub repo with reproducible code: https://github.com/arunac97/HeadlessApp (Contains Java code and the canvas-drawing JS.)

🧪 Test Cases:

  1. Case 1 (multi-page, fixed dimensions): Canvas misaligns. https://github.com/arunac97/HeadlessApp/blob/main/case1.pdf

  2. Case 2 (single tall page using getLayoutMetrics): Extra blank space at bottom. https://github.com/arunac97/HeadlessApp/blob/main/case2.pdf

Thanks!

6
  • @KJ Thank you for your response and explanation about how PDFs handle media boundaries—much appreciated! Just to clarify a few things from my side: This sample site is just for testing purposes. In reality, the URL will vary depending on the use case, so the PDF rendering needs to work consistently across different pages. Commented Jul 6 at 6:12
  • @KJ I’m not generating PDFs only for the mobile version—the same process will be applied for desktop and tablet versions too, using different device metrics. I mentioned the "30% extra space" to highlight that the issue is not caused by pixel-to-inch rounding errors. The extra blank space is quite significant and seems unrelated to minor unit conversions. Commented Jul 6 at 6:13
  • @KJ My main concern is this: I'm passing an exact paperWidth and paperHeight to Page.printToPDF, based on the actual layout size from Page.getLayoutMetrics. I expect Chrome to render the content onto a PDF with those exact dimensions. But from the output, it feels like something else is happening during rendering—as if Chrome isn't respecting the dimensions I passed in. Commented Jul 6 at 6:18
  • @KJ the sample output here fileport.io/4T1E1NB97VpN Commented Jul 6 at 6:36
  • @KJ Thanks for the input, but I think the actual issue might’ve been misunderstood. I’ve shared my Java and JS code here: github.com/arunac97/HeadlessApp. The goal is to inject JS on any site (e.g. arunac97.github.io/samplesite.com/newcanvas.html), draw a full-page canvas, and export to PDF. Case 1: Fixed page size causes canvas misalignment — case1.pdf Case 2: Full layout size adds huge white space — case2.pdf Would really appreciate any suggestions or workaround! Commented Jul 7 at 18:24

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.