Recommended Free Tools
Most jsPDF/html2canvas alignment bugs come from mixing three coordinate systems: CSS pixels in the page, bitmap pixels in the canvas, and the PDF units used by jsPDF. Freeze the export layout, capture with explicit dimensions, then convert the canvas aspect ratio to a deliberate PDF width and height. Keep html2canvas’s scale for sharpness only; never use it as the PDF size.
Why the PDF does not match the browser
A browser lays out elements in CSS pixels. html2canvas paints that layout into a bitmap whose pixel dimensions are affected by scale. jsPDF then places that bitmap using its own unit system (millimetres, points, inches, or another configured unit). The numbers are not interchangeable.
| Layer | What its numbers mean | Typical mistake |
|---|---|---|
| CSS layout | Element positions, widths and line wrapping in CSS pixels | Allowing a responsive breakpoint or a changing viewport to alter the layout during export |
| Canvas bitmap | Raster pixels produced by html2canvas; scale changes density and therefore canvas dimensions |
Passing canvas.width directly to jsPDF as if it were millimetres or points |
| PDF placement | The x, y, width and height supplied to jsPDF in the document’s configured units | Using canvas pixels as PDF coordinates, which makes everything uniformly too large or too small |
Convert only at the addImage boundary. Choose the PDF width you want, derive the height from the canvas aspect ratio, and leave the bitmap’s resolution independent of its placement size.
1. Freeze the source layout before capturing
Give the export container a fixed width
Responsive CSS is useful on screen but dangerous in an export. Apply an export class or inline style that sets a known width, prevents an unintended breakpoint, and includes all content that should appear. Record the actual dimensions so you can compare a failing PDF with the source:
Free tools Windows power users keep installed
One-click scans. No signup required.
#1 Best Overall
- Create and edit PDFs. Collaborate with ease. E-sign documents and collect signatures. Get everything done in one app, wherever you go.
- Edit text and images without jumping to another app.
- E-sign documents or request e-signatures on any device. Recipients don’t need to log in to e-sign.
- Convert PDFs to editable Microsoft Word, Excel, or PowerPoint documents.
- Share PDFs for collaboration. Commenting features make it easy for reviewers to comment, mark up, and annotate.
const node = document.querySelector('#invoice');
const rect = node.getBoundingClientRect();
console.log({
cssWidth: rect.width,
cssHeight: rect.height,
scrollWidth: node.scrollWidth,
scrollHeight: node.scrollHeight
});
Use scrollWidth and scrollHeight when the element contains content below the visible viewport. Do not let a page scroll position move the capture origin; set scrollX and scrollY to zero.
Wait for fonts and images
Capture after web fonts have loaded and images have decoded. Otherwise text metrics can change between layout and rasterization, producing different wrapping or apparent spacing. A practical browser sequence is:
await document.fonts.ready;
await Promise.all(
[...document.images].map(img => img.complete
? Promise.resolve()
: new Promise(resolve => {
img.addEventListener('load', resolve, { once: true });
img.addEventListener('error', resolve, { once: true });
}))
);
2. Capture with explicit html2canvas geometry
Set the viewport dimensions to the export container rather than inheriting whatever size the user currently has. scale controls rendering density; it does not set the eventual PDF size.
const canvas = await html2canvas(node, {
scale: 2,
width: node.scrollWidth,
height: node.scrollHeight,
windowWidth: node.scrollWidth,
windowHeight: node.scrollHeight,
scrollX: 0,
scrollY: 0,
useCORS: true
});
A scale of 2 is a starting point, not a universal optimum. Increasing it can make text and fine lines sharper, but it also increases memory use and canvas dimensions. Keep the export container width and PDF placement width unchanged when experimenting with scale, so you can distinguish a resolution problem from a geometry problem.
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 →Rank #2
- Create and edit PDFs. Collaborate with ease. E-sign documents and collect signatures. Get everything done in one app, wherever you go.
- Edit text and images without jumping to another app.
- E-sign documents or request e-signatures on any device. Recipients don’t need to log in to e-sign.
- Convert PDFs to editable Microsoft Word, Excel, or PowerPoint documents.
- Share PDFs for collaboration. Commenting features make it easy for reviewers to comment, mark up, and annotate.
3. Convert the bitmap to PDF units once
The following browser example creates an A4 PDF in millimetres with a 10 mm margin. It preserves the canvas aspect ratio, so text is not stretched and the right edge does not drift.
async function exportElementToPdf() {
const node = document.querySelector('#invoice');
await document.fonts.ready;
const canvas = await html2canvas(node, {
scale: 2,
width: node.scrollWidth,
height: node.scrollHeight,
windowWidth: node.scrollWidth,
windowHeight: node.scrollHeight,
scrollX: 0,
scrollY: 0,
useCORS: true
});
const pdf = new jsPDF({ unit: 'mm', format: 'a4' });
const pageWidth = pdf.internal.pageSize.getWidth();
const pageHeight = pdf.internal.pageSize.getHeight();
const margin = 10;
const pdfWidth = pageWidth - margin * 2;
const pdfHeight = canvas.height * pdfWidth / canvas.width;
// One conversion: bitmap aspect ratio to PDF placement units.
pdf.addImage(canvas, 'PNG', margin, margin, pdfWidth, pdfHeight);
pdf.save('invoice.pdf');
}
exportElementToPdf();
If you use points or inches instead of millimetres, the same formula applies: calculate the available width in the PDF’s configured unit and derive the height from canvas.height / canvas.width.
4. Handle documents taller than one page
Slice the rendered canvas
A single very tall bitmap can exceed a browser’s canvas limit. When that happens, output may be blank or only partly rendered without an exception. Render at a manageable width, calculate a page-sized slice, and add each slice at the same PDF width. Keep the scale and content width constant on every page.
function addCanvasPages(pdf, canvas, margin = 10) {
const pageWidth = pdf.internal.pageSize.getWidth();
const pageHeight = pdf.internal.pageSize.getHeight();
const pdfWidth = pageWidth - margin * 2;
const pxPerPdfUnit = canvas.width / pdfWidth;
const sliceHeightPx = Math.floor((pageHeight - margin * 2) * pxPerPdfUnit);
let offsetY = 0;
let page = 0;
while (offsetY < canvas.height) {
const heightPx = Math.min(sliceHeightPx, canvas.height - offsetY);
const slice = document.createElement('canvas');
slice.width = canvas.width;
slice.height = heightPx;
slice.getContext('2d').drawImage(
canvas,
0, offsetY, canvas.width, heightPx,
0, 0, canvas.width, heightPx
);
if (page > 0) pdf.addPage();
const pdfHeight = heightPx / pxPerPdfUnit;
pdf.addImage(slice, 'PNG', margin, margin, pdfWidth, pdfHeight);
offsetY += heightPx;
page += 1;
}
}
Slicing can split a paragraph or table row. If clean page breaks matter, add print-oriented break classes to the source and use jsPDF’s HTML module with its page-break settings, or paginate the source markup yourself before rasterizing. The important invariant is a constant content width and scale ratio; changing either between pages changes wrapping.
Rank #3
- Perfect Adobe Acrobat Pro alternative – lifetime license for Windows 10 and 11.
- EDIT text, images, pages, hyperlinks, designs in PDF documents. ORGANIZE PDFs.
- READ and Comment on PDFs – Intuitive reading modes & document commenting and mark up tools!
- CREATE, COMBINE, SCAN and COMPRESS PDFs.
- FILL forms & Digitally Sign PDFs. Work with Digital certificates
5. Align text created directly by jsPDF
If you call pdf.text(), html2canvas is not involved. The text has its own anchor, baseline and spacing controls. Make them explicit instead of relying on defaults:
pdf.text('Invoice total', x, y, {
align: 'right',
baseline: 'alphabetic',
charSpace: 0,
horizontalScale: 1,
lineHeightFactor: 1.15,
maxWidth: 60
});
Choose the correct anchor
- Left-aligned text: treat
xas the left anchor. - Centered text: calculate the intended center and set
align: 'center'; do not subtract an estimated string width yourself. - Right-aligned text: set
align: 'right'and use the right edge asx.
baseline determines how the y coordinate relates to the glyphs. charSpace changes tracking, horizontalScale changes glyph width, lineHeightFactor controls multiline leading, and maxWidth constrains wrapping. A wrong anchor often looks like a spacing bug because every line is displaced by a similar amount.
6. Fix images, CSS and browser limitations
Cross-origin images
Images loaded from another origin can taint the canvas. The browser may then reject toDataURL() or produce a missing image. Keep assets same-origin, or configure the image server with suitable CORS response headers and capture with useCORS: true. If you cannot change the remote server, route the image through a same-origin proxy that adds the required headers.
Unsupported CSS
html2canvas reconstructs a page from browser APIs and manually implemented CSS properties; it does not implement every CSS feature. A layout that is correct in Chrome can therefore differ in the canvas. For an export-only stylesheet, replace unsupported effects with simpler layout rules, flatten critical decorations into images, or reproduce the design with direct jsPDF drawing/text.
Rank #4
- EDIT text, images & designs in PDF documents. ORGANIZE PDFs. Convert PDFs to Word, Excel & ePub.
- READ and Comment PDFs – Intuitive reading modes & document commenting and mark up.
- CREATE, COMBINE, SCAN and COMPRESS PDFs
- FILL forms & Digitally Sign PDFs. PROTECT and Encrypt PDFs
- LIFETIME License for 1 Windows PC or Laptop. 5GB MobiDrive Cloud Storage Included.
Browser-only execution
html2canvas relies on window, document and computed styles. It is not a drop-in Node.js renderer. Run it in a browser, a browser automation environment, or another runtime that supplies those APIs.
Symptom-to-cause troubleshooting
| Symptom | Likely cause | Correction |
|---|---|---|
| Everything is uniformly too wide or narrow | Canvas pixels were passed as PDF units | Choose a PDF-unit width and derive height from the canvas aspect ratio. |
| Text wraps differently from the page | The capture viewport differs from the layout viewport | Set the export container width plus windowWidth and windowHeight. |
| Geometry is correct but text is blurry | Bitmap scale is too low | Increase scale while keeping PDF placement dimensions unchanged. |
| Centered or right-aligned text is shifted | The direct jsPDF text anchor or align option is wrong |
Set the intended alignment and calculate x from that anchor. |
| Bottom content is missing | Visible viewport dimensions were used instead of scroll dimensions, or the canvas is too large | Use scrollWidth/scrollHeight; reduce capture size or paginate. |
Images vanish or toDataURL fails |
Cross-origin canvas tainting | Use CORS headers with useCORS or a same-origin proxy. |
| A CSS effect is ignored | html2canvas does not support that property | Simplify export CSS, replace the property, or draw that part directly in jsPDF. |
| Output is blank with no useful exception | The canvas exceeded a browser limit | Lower scale, reduce the capture area, or render and add page-sized slices. |
Choosing raster capture, direct text or the HTML module
| Approach | Best when | Trade-off |
|---|---|---|
html2canvas plus addImage |
You need the browser appearance, including complex layout, in a predictable snapshot | Text is rasterized; resolution, CORS and canvas-size limits apply. |
Direct pdf.text() and drawing APIs |
You need selectable, measurable text and exact anchors | You must recreate layout, wrapping, fonts and spacing yourself. |
jsPDF.html() |
You want jsPDF to interpret HTML and page-break settings | HTML/CSS support and pagination still require validation against the target document. |
Use raster capture for a faithful visual copy, direct text for reports where typography and searchability matter most, and a hybrid when headers, totals or tables need vector precision while decorative content can remain an image.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Performance and reliability checklist
- Measure the export container and log its dimensions before capture.
- Wait for fonts and images; do not capture while layout is still changing.
- Start with a controlled scale, then increase it only if sharpness requires it.
- Keep the same content width on every page and derive heights mathematically.
- Test long pages, missing images, slow network responses and narrow layouts.
- Watch memory usage when scale or page height grows; paginate before the browser silently returns a partial canvas.
- Keep a direct-jsPDF fallback for critical text when a CSS feature cannot be reproduced by html2canvas.
Or skip the browser setup
If your source is a public URL and you need a clean screenshot or PDF rather than a custom in-page jsPDF layout, ScreenshotNeo provides a single HTTP request. It accepts consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result.
cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
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)
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}`);
const bytes = await res.arrayBuffer();
await Bun.write('shot.webp', bytes);
See the ScreenshotNeo documentation for image and PDF parameters. Its MCP server supplies take_screenshot, get_page_info and capture_pdf tools to Claude, Cursor and other MCP clients. One thousand screenshots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.
FAQ
Should I match PDF width to CSS width?
No. Match the aspect ratio, not the numeric units. CSS and canvas widths describe pixels; the PDF width describes millimetres, points or another document unit.
Best Value
- Full-featured PDF Editor: Edit text in the document
- Fully convert PDF to Word and Excel and continue editing
- NEW: Further development of existing functions
- NEW: Even faster and more user-friendly
- NEW: Over 75 small improvements in all areas
Can I make text sharper without changing its position?
Yes. Increase html2canvas scale and keep the same jsPDF x, y, width and derived height. Higher scale affects bitmap detail, not placement.
Why does the same export differ between browsers?
Font availability, browser layout behavior, CSS support and canvas limits can differ. Freeze dimensions, load the same assets, and validate in each browser you support.
When should I avoid html2canvas entirely?
Avoid it when selectable vector text, exact typographic metrics, or unsupported CSS are non-negotiable. Build those parts with jsPDF’s direct text and drawing APIs instead.
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 minuteFrequently Asked Questions
Can I make a responsive page export at mobile width?
Yes. Set the export container and html2canvas window dimensions to the intended mobile CSS width, then calculate the PDF placement from the resulting canvas aspect ratio.
Does increasing PDF width improve raster quality?
No. PDF placement width only changes physical size. Increase html2canvas scale for more bitmap pixels, subject to memory and canvas limits.
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.

