Render the HTML in a real browser on an explicitly sized A4 canvas, wait for fonts, images, and JavaScript to finish, then export that canvas as a JPEG. For portrait A4, use 210mm × 297mm (8.27in × 11.7in); for landscape, use 297mm × 210mm. Because JPEG is a pixel format, also choose a density: about 794 × 1123 pixels at 96 ppi, 1240 × 1754 at 150 ppi, or 2480 × 3508 at 300 ppi.
The reliable workflow below uses Playwright or Puppeteer, keeps content inside the A4 page, waits for rendering to settle, and verifies the resulting file dimensions before you print or distribute it.
A4 size: physical dimensions and JPG pixels
A4 defines a physical sheet, not a single universal image resolution. Its portrait dimensions are 210mm × 297mm (8.27in × 11.7in). Landscape reverses those measurements. A JPG needs a pixel width and height, so multiply the inch dimensions by your chosen pixels-per-inch (ppi) assumption.
| Target density | Portrait pixels | Landscape pixels | Typical use |
|---|---|---|---|
| 96 ppi | 794 × 1123 | 1123 × 794 | Browser previews and ordinary screen sharing |
| 150 ppi | 1240 × 1754 | 1754 × 1240 | General documents and moderate-quality printing |
| 300 ppi | 2480 × 3508 | 3508 × 2480 | Sharp print output and small text |
These values are arithmetic from the documented A4 dimensions and the stated ppi assumptions. They are not separate browser standards. If a print shop specifies a different resolution, use that specification instead.
Recommended Free Tools
#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Prepare the HTML for one A4 page
Use a physical-size page element
Put all content inside a page wrapper whose CSS width and height are measured in millimetres. box-sizing: border-box makes borders and padding part of the declared size rather than adding to it.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
@page { size: A4 portrait; margin: 0; }
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body { background: #e8e8e8; }
.page {
width: 210mm;
height: 297mm;
padding: 16mm;
background: #fff;
overflow: hidden;
font-family: Arial, sans-serif;
color: #111;
}
h1 { margin: 0 0 8mm; font-size: 26pt; }
p { margin: 0 0 5mm; font-size: 11pt; line-height: 1.45; }
</style>
</head>
<body>
<main class="page">
<h1>Your A4 document</h1>
<p>Replace this content with the HTML you need to export.</p>
</main>
</body>
</html>
Control margins, bleed, and overflow
Reset the browser’s default body margin. Decide whether the JPG includes a bleed (artwork extending beyond the trim edge) or a safe margin. Keep text, logos, and other critical details inside the safe area. A fixed-height page with overflow: hidden prevents accidental spill, but it can also clip content; measure or paginate deliberately instead of hiding a mistake.
Use print CSS only when it helps
@page is the CSS print-layout rule for page dimensions and print properties. It is useful when you first create an A4 PDF or when your styles have print-specific rules. For a direct screenshot, the explicit .page element and a deterministic viewport are the important controls.
Convert HTML to an A4 JPG with Playwright
Playwright’s screenshot API supports jpeg. Its scale option is significant: "css" emits one image pixel per CSS pixel, while device scaling can emit more pixels on a high-DPI device. Set it deliberately and inspect the output rather than assuming the browser’s screen density.
Complete Node.js example
Install Playwright with npm install playwright, save your document as document.html, then run this script:
Rank #2
const { chromium } = require('playwright');
const path = require('path');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage({
viewport: { width: 794, height: 1123 },
deviceScaleFactor: 1
});
await page.goto('file://' + path.resolve('document.html'), {
waitUntil: 'networkidle'
});
await page.evaluate(async () => {
await document.fonts.ready;
await Promise.all(Array.from(document.images).map(img => {
if (img.complete) return Promise.resolve();
return new Promise(resolve => {
img.addEventListener('load', resolve, { once: true });
img.addEventListener('error', resolve, { once: true });
});
}));
});
await page.addStyleTag({
content: '* { animation: none !important; transition: none !important; }'
});
await page.locator('.page').screenshot({
path: 'a4.jpg',
type: 'jpeg',
quality: 92,
scale: 'css'
});
await browser.close();
})();
With a 794 × 1123 CSS viewport and scale: 'css', the expected portrait output is approximately 794 × 1123 pixels. For a 300-ppi target, use a 2480 × 3508 viewport (or an equivalent device scale) and keep scale choices consistent.
Capture a full page when its height is not fixed
page.screenshot({ fullPage: true }) captures the document’s complete scrollable height. That is appropriate for a long web page, not for a single A4 sheet. For multiple A4 pages, create one fixed-size wrapper per page and capture each wrapper, or generate an A4 PDF first and rasterize each PDF page. Do not silently squeeze a multi-page document into one image.
Convert HTML to an A4 JPG with Puppeteer
Puppeteer provides setContent() for injecting HTML, viewport controls, and page.screenshot(). This example keeps the same readiness checks and captures the A4 element.
Crashes, 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 minuteWindows 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 reinstallconst puppeteer = require('puppeteer');
const fs = require('fs');
(async () => {
const html = fs.readFileSync('document.html', 'utf8');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 794, height: 1123, deviceScaleFactor: 1 });
await page.setContent(html, { waitUntil: 'networkidle0' });
await page.evaluate(async () => {
await document.fonts.ready;
await Promise.all(Array.from(document.images).map(img => {
if (img.complete) return Promise.resolve();
return new Promise(resolve => {
img.onload = img.onerror = resolve;
});
}));
});
await page.addStyleTag({
content: '* { animation: none !important; transition: none !important; }'
});
const element = await page.$('.page');
await element.screenshot({ path: 'a4.jpg', type: 'jpeg', quality: 92 });
await browser.close();
})();
Make the render deterministic
Wait for fonts and images
networkidle only describes network activity; a web font may still be applying and an image may have a completed request but not a usable layout. Waiting for document.fonts.ready and each image’s completion avoids shifted text and blank image boxes.
Wait for client-side data
If JavaScript fills the page after load, wait for a meaningful selector rather than a guessed delay. In Playwright, for example, wait for page.locator('.report-ready').waitFor() after your application adds that marker. A delay can be a fallback for animations or third-party widgets, but it is less reliable than a state-based signal.
Rank #3
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Disable motion and control external resources
Animations can produce different pixels on every run. Disable transitions and animations during capture. If external fonts, images, or API data are unavailable in your build environment, inline them or provide deterministic test fixtures. Check cross-origin permissions when canvas-based content is involved.
Check the JPG before sending it to print
- Verify the file’s actual width and height with an image viewer or an image-metadata tool.
- Open the image at 100% and inspect small text, hairlines, logos, and image sharpness.
- Confirm that no content is clipped at the bottom or right edge.
- Check that the printer or document system interprets the intended physical size; pixel dimensions alone do not guarantee a 1:1 print size.
- For professional printing, ask whether 300 ppi, an embedded color profile, bleed, or crop marks are required.
Common failures and fixes
The output is the wrong pixel size
Cause: the viewport, device scale factor, or screenshot scale was not explicit. Fix: set both viewport dimensions and scale, then verify the file. Remember that CSS pixels and device pixels are different units.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Text or images are clipped
Cause: content exceeds the fixed 210mm × 297mm box, or padding was added outside the declared size. Fix: keep box-sizing: border-box, reduce content or font size, add a second page, and inspect overflow rather than hiding it.
Fonts change between runs
Cause: capture started before web fonts finished loading, or the font was unavailable. Fix: await document.fonts.ready, self-host or preload required fonts, and confirm the computed font family.
Images are blank
Cause: lazy loading, an image error, blocked authentication, or a capture taken before decoding. Fix: scroll or otherwise trigger lazy images, wait for completion, check the browser console and response status, and provide valid credentials or local assets where required.
Rank #4
The page contains a cookie banner, popup, or chat bubble
Cause: those elements are part of the live page at capture time. Fix: dismiss them in setup code, hide known selectors, or use a renderer that can remove common consent and overlay components before the shot.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
JavaScript content is missing
Cause: the script failed, an API request timed out, or capture happened before the app’s ready state. Fix: wait for a page-specific ready selector, inspect console and network errors, and increase the navigation timeout only after fixing the underlying failure.
A long document is squeezed into one page
Cause: a full document was forced into one fixed-height element. Fix: paginate into separate A4 wrappers or create an A4 PDF and rasterize each page independently.
Performance, reliability, and cost choices
Higher pixel targets require more browser memory and produce larger JPEGs. Capture only the page element when possible instead of the entire browser viewport. Reuse a browser process for batches, but create an isolated page for each URL and close pages promptly. Set navigation and resource timeouts, retry transient network failures with a limit, and log the URL, viewport, scale, and output dimensions so a bad image can be reproduced.
JPEG quality is a trade-off: increase it for text and thin lines, then compare file size. JPEG is lossy; use PNG instead when the artwork contains flat UI colors, transparency, or text that shows compression artifacts. If the final destination is a PDF, generating an A4 PDF first may preserve pagination and vector text better than rasterizing HTML directly.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesBest Value
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request renders a URL as a clean PNG, JPEG, WebP, or PDF. It accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. 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.
For a JPEG endpoint call, see the ScreenshotNeo documentation:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same API supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or any viewport, retina scale, custom CSS and JavaScript, clicks before capture, hidden selectors, waits for a selector, delay, or network idle, blocked ads/trackers/requests/resource types, custom headers, cookies, user agents and Authorization, timezone and geolocation, transparent backgrounds, resizing, selectable cache TTL, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, easing 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(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
The API’s free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan, and yearly billing provides two months free. Sign up for the free ScreenshotNeo plan to try it without a card.
Frequently Asked Questions
Should I use 96, 150, or 300 ppi for an A4 JPG?
Use 96 ppi for screen-focused previews, 150 ppi for ordinary documents, and 300 ppi when small text or print sharpness matters. Follow your printer’s specification when one is provided.
Can I convert an A4 HTML document to one JPG if it has several pages?
No single fixed-height canvas can represent several sheets without either clipping or shrinking. Create one A4 image per page, or make an A4 PDF and rasterize each page.
Why does an A4 JPG print at the wrong physical size?
A JPG stores pixels; printing software may apply its own scaling. Set the output pixel dimensions and choose 100% or actual-size printing, then confirm the printer’s margins and paper settings.
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.

