To resize HTML reliably in jsPDF, set width in the html() options to the PDF space you want, and set windowWidth to the CSS-pixel width at which the element should be laid out. Put rendering controls such as scale, canvas dimensions and cross-origin handling inside html2canvas. The two widths solve different problems: width controls PDF placement, while windowWidth controls the rendered container.
The working pattern
This example exports an element to an A4 PDF with 24-point margins. It measures the element’s scrollable CSS width and height, maps the content into the available PDF width, and keeps pagination text-aware.
const element = document.querySelector('#export');
const pdf = new jsPDF({
unit: 'pt',
format: 'a4',
orientation: 'portrait'
});
const pageWidth = pdf.internal.pageSize.getWidth();
const margin = 24;
pdf.html(element, {
margin,
width: pageWidth - (margin * 2),
windowWidth: element.scrollWidth,
autoPaging: 'text',
html2canvas: {
scale: 1,
windowWidth: element.scrollWidth,
windowHeight: element.scrollHeight,
useCORS: true
},
callback: (doc) => doc.save('export.pdf')
});
In this code, width is expressed in jsPDF document units (points here). The rendered element is scaled so it fits that width. windowWidth is expressed in CSS pixels and determines the width of the temporary rendering container. Supplying windowWidth alone is not enough: jsPDF documents that it has an effect only when width is also supplied. A separately specified html2canvas.scale can also prevent jsPDF’s width fitting from behaving as expected, so use scale for pixel density and use width for PDF layout.
What each size option actually controls
width: the target width in the PDF
Use width when the question is “How wide should this content be on the PDF page?” Calculate the page’s usable width after margins rather than hard-coding a value. If your document uses millimetres, inches or another unit, the value follows the unit passed to new jsPDF().
#1 Best Overall
- 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.
For example, a landscape A4 document has a different usable width from portrait A4. Reading pdf.internal.pageSize.getWidth() keeps the calculation correct when orientation or format changes.
windowWidth: the CSS layout viewport
windowWidth controls the CSS-pixel width used while jsPDF prepares the element. It affects the actual container size, but it does not change CSS media queries. Set it to the layout width you designed for, commonly element.scrollWidth or a deliberate desktop/mobile width.
If the source element is 1,200 CSS pixels wide and you want its desktop layout preserved, use 1,200 for windowWidth, then fit that layout into the PDF with width. If you instead use a narrow value, responsive rules and natural wrapping can produce a different document.
html2canvas.scale: raster resolution
html2canvas uses a scale factor for the canvas bitmap. Its default is the browser’s window.devicePixelRatio. Increasing scale can make text and images sharper, but it increases memory use, rendering time and output size. It is not a substitute for width. If you need a different physical PDF width, change width; if you need more or fewer bitmap pixels, change scale.
windowHeight: how much vertical content is rendered
For long or scrollable elements, match html2canvas’s windowHeight to element.scrollHeight. A viewport-sized value can capture only the visible portion or produce an incomplete canvas.
A complete browser implementation
Give the export element a stable width and wait until fonts and images are ready before calling html(). Measuring after layout avoids a common failure where a web font or lazy image changes the dimensions during capture.
async function exportElement() {
const element = document.querySelector('#export');
if (!element) throw new Error('Missing #export element');
if (document.fonts?.ready) {
await document.fonts.ready;
}
await Promise.all(
[...element.querySelectorAll('img')].map(img =>
img.complete ? Promise.resolve() : new Promise(resolve => {
img.addEventListener('load', resolve, { once: true });
img.addEventListener('error', resolve, { once: true });
})
)
);
const pdf = new jsPDF({ unit: 'pt', format: 'a4' });
const margin = 24;
const cssWidth = element.scrollWidth;
const cssHeight = element.scrollHeight;
pdf.html(element, {
margin,
width: pdf.internal.pageSize.getWidth() - margin * 2,
windowWidth: cssWidth,
autoPaging: 'text',
html2canvas: {
scale: 1,
windowWidth: cssWidth,
windowHeight: cssHeight,
useCORS: true,
backgroundColor: '#ffffff'
},
callback: doc => doc.save('document.pdf')
});
}
document.querySelector('#export-button').addEventListener('click', exportElement);
Use autoPaging: 'text' for primarily text-based, single-column content. It attempts to avoid cutting text across page boundaries. The alternatives are false, true or 'slice'. Slice mode may split shapes and text chunks wherever a page boundary occurs; it can be acceptable for dashboards or image-heavy layouts but is less pleasant for prose.
Choosing dimensions for common layouts
Fit a desktop design into a portrait page
Keep windowWidth at the desktop CSS width, such as element.scrollWidth, and set width to the page’s usable width. This preserves the desktop arrangement while uniformly scaling it into the PDF.
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 →Export a responsive mobile layout
Choose a mobile CSS width explicitly, for example 390, and pass that value as windowWidth. Set width to the PDF’s usable width. This asks the renderer to lay out the content as mobile first, then place that result on the page.
Capture a wide table
Decide whether readability or one-page fit matters more. A large windowWidth preserves columns but can make text tiny when reduced to page width. Consider landscape orientation, a smaller table-specific font, or splitting the table into sections. Increasing scale will not create more physical page width.
Rank #2
- Edit PDFs with Ease. Modify text, images, and layouts directly within your PDF documents.
- Convert & Organize. Export PDFs to Word, Excel, or ePub, and organize files with ease.
- Read & Annotate. Enjoy intuitive reading modes and powerful tools to comment, highlight, and mark up PDFs.
- Create & Manage PDFs. Create new PDFs, combine multiple files, scan documents, and compress for easy sharing.
- Fill & Sign Forms. Complete forms and digitally sign documents with secure e-signature tools.
Use a fixed export stylesheet
A print stylesheet can make dimensions deterministic:
@media print {
#export { width: 960px; }
#export .interactive-only { display: none; }
}
Remember that windowWidth does not alter media-query evaluation. If your design depends on breakpoints, test the actual browser viewport and the html2canvas rendering behavior rather than assuming a width value will switch every breakpoint.
When width appears to do nothing
windowWidthwas supplied withoutwidth. Add both options; the container width option only has an effect when target PDF width is defined.- A fixed
html2canvas.scaleconflicts with expectations. Remove it while diagnosing layout, then add a deliberate scale for resolution. - The source has an unexpected scroll width. Inspect
element.scrollWidth, overflowing children, transforms and absolutely positioned elements. - CSS is reflowing. Set the intended CSS width and check breakpoint-dependent rules. The rendering viewport does not rewrite media queries.
- The page is clipping content. Supply matching
windowWidthandwindowHeightvalues based on scroll dimensions.
Images, fonts and cross-origin content
html2canvas reconstructs a page from DOM and styles; it does not take a native browser screenshot. Every CSS property must be implemented individually, so CSS support is not complete. Complex filters, blend modes, certain form controls, video and browser-specific effects should be tested in every browser you support.
Cross-origin images can taint the canvas. useCORS: true works only when the image server returns an appropriate Access-Control-Allow-Origin header. If you control neither server nor headers, serve the asset through a same-origin proxy, or replace it with a permitted copy. A missing image may otherwise cause a blank, partial or failed export.
Wait for web fonts and images before measuring. Lazy-loaded images may not exist until they enter a viewport; ensure they are loaded or provide explicit dimensions so late layout shifts do not move page breaks.
Canvas limits, pagination and file size
Browser canvas maximum dimensions vary by browser and device. Very large windowWidth, windowHeight or scale values can yield blank or partial output without a useful exception. For long documents, export sections separately, reduce scale, or reduce the rendered CSS dimensions.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Because html2canvas produces a raster representation for jsPDF, text in this workflow is generally not selectable or searchable, and files can become large. Lowering scale reduces pixels and size but can reduce legibility. If selectable text, semantic structure or highly faithful CSS is mandatory, use a browser PDF print pipeline rather than relying solely on a canvas-based conversion.
Browser versus server-side generation
html2canvas requires browser APIs such as window, document and computed styles. It cannot run directly in Node.js. For server-side generation, drive a real browser with a tool such as Puppeteer or Playwright, load the page, wait for fonts and images, and use the browser’s PDF facility. That approach changes the implementation and operational requirements: you must manage a browser runtime, navigation failures, authentication and resource limits.
html2pdf.js is another client-side route that combines html2canvas and jsPDF. Its documented behavior includes resizing the root element to fit a PDF page, which can trigger internal reflow. Its output is rendered as an image, so selectable text is not available and files may be large. Use it when that trade-off is acceptable, and inspect the resulting layout with the same width and asset checks described above.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. A single request returns PNG, JPEG, WebP or PDF, so you do not need to ship html2canvas and jsPDF in a browser for a URL you can access.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsRank #3
- EVERY PDF TOOL UNLOCKED - 30+ tools in one app: edit text and images, convert, merge, split, compress, sign, OCR, redact, watermark, batch process, and more. No feature gates, no upsells, nothing held back.
- PAY ONCE, OWN FOREVER — A one-time purchase, not a subscription. Other apps runs $240/year — Scrivar is yours for life, with free updates included.
- UNLIMITED eSIGN, BUILT IN — Send contracts and forms for signature and track every step. Recipients sign in their browser with no account or app needed. Replace DocuSign and save hundreds a year.
- PC, MAC, AND WEB — Install on any Win 10/11 PC or macOS 11+ Mac (Intel or Apple Silicon), or work in your browser at scrivar.com. Same tools, same account, everywhere you work.
- OCR + FULL OFFICE CONVERSION — Turn scanned documents into searchable, selectable text, and convert PDFs to and from Word, Excel, and PowerPoint with formatting kept intact.
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 parameters and PDF options. Equivalent calls:
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)
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 bytes = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));
Before capture, ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. 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. Its MCP server includes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Troubleshooting checklist
Blank PDF
- Check that the selector resolves and is attached to the document.
- Reduce canvas dimensions or scale to stay below browser limits.
- Wait for fonts and images; inspect cross-origin responses.
- Confirm the element is not hidden with
display:noneor zero dimensions at capture time.
Only the visible portion appears
Use the element’s full scrollWidth and scrollHeight for both jsPDF/html2canvas viewport options. Remove ancestor overflow constraints temporarily to identify clipping.
Images are missing
Use same-origin assets or configure CORS correctly. useCORS cannot grant permission that the image server does not provide.
Free tools Windows power users keep installed
One-click scans. No signup required.
Text is too small
Do not increase scale expecting larger text on paper. Increase the PDF target width by changing orientation or margins, reduce the source layout width, split content across pages, or use a browser PDF pipeline with selectable text.
Page breaks split headings or paragraphs
Use autoPaging: 'text', add print-aware break rules, and avoid very tall unbreakable containers. Text mode is an attempt, not a guarantee for every CSS layout.
Practical decision guide
| Need | Primary setting | Trade-off |
|---|---|---|
| Fit content to page | width plus PDF margins |
Wide layouts may become small |
| Preserve desktop/mobile layout | windowWidth |
Does not rewrite media queries |
| Sharper raster output | html2canvas.scale |
More memory, time and file size |
| Long prose pagination | autoPaging: 'text' |
Not perfect for complex columns or graphics |
| Remote images | useCORS or same-origin proxy |
Requires server permission headers |
| Server-side rendering | Puppeteer or Playwright browser PDF | Requires browser infrastructure |
Frequently Asked Questions
Can I set only html2canvas width to resize the PDF?
No. Use jsPDF’s html() width for PDF placement and html2canvas dimensions for the rendered canvas. For responsive layout, also provide windowWidth.
Does windowWidth change CSS breakpoints?
No. It changes the rendering container’s size; it does not change CSS media-query evaluation.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Why does increasing scale not make the PDF content wider?
Scale changes bitmap resolution. Use width or the page format and margins to change physical PDF width.
Can html2canvas run in a Node.js script?
Not directly. It requires browser APIs, so use a browser-driving runtime such as Puppeteer or Playwright for server-side work.
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.

