How to convert HTML to PDF for free: 3 methods that actually work
The simplest free way to convert HTML to PDF is your browser: open the file, press Ctrl+P (Cmd+P on Mac), choose “Save as PDF” and turn on background graphics. For a one-click visual copy, html2canvas with jsPDF screenshots the page into a PDF. Developers can automate the job with headless Chrome or Puppeteer’s page.pdf().
Which free method should you use?
All three methods are free and none of them needs an online service that uploads your file. They differ in one important way: whether the PDF contains real text (selectable, searchable, small) or a picture of the page (looks exactly like the screen, but the text cannot be selected).
If you just want the result without installing anything, our free HTML to PDF converter runs methods 1 and 2 for you in the browser, with fixes for the usual problems of modern pages. The table below sums up the trade-offs.
| Browser print | html2canvas + jsPDF | Headless Chrome / Puppeteer | |
|---|---|---|---|
| Text in the PDF | Real text, selectable and searchable | Image only, not selectable | Real text, selectable and searchable |
| Visual fidelity | Good, but follows print CSS (backgrounds may drop) | Very close to the screen | Same engine as Chrome print, fully scriptable |
| File size | Small | Large (one image per page) | Small |
| Setup | None | Add two scripts to the page | Chrome or Node.js on your machine |
| Privacy | Stays on your computer | Stays in the browser | Stays on your machine or server |
| Best for | Reports, articles, invoices | Dashboards, posters, “looks exactly like this” | Batch jobs and automated exports |
Method 1: Print → Save as PDF in your browser
Every modern browser can write a PDF through its print dialog. The text stays real text, links usually stay clickable, and the file is small. It is the method to try first.
- Open the .html file in Chrome, Edge, Firefox or Safari (double-click it or drag it onto a browser window).
- Wait until fonts, images and charts have finished loading.
- Press Ctrl+P on Windows or Linux, Cmd+P on Mac.
- Chrome and Edge: set Destination to “Save as PDF”. Firefox: choose “Save to PDF”. Safari: use File → Export as PDF, or the PDF menu in the print dialog.
- Open “More settings” (Chrome/Edge) and tick “Background graphics”; in Firefox the option is “Print backgrounds”; in Safari click “Show Details” and tick “Print backgrounds”.
- Pick the paper size (A4 or Letter), orientation and margins, untick “Headers and footers” if you do not want the date and file path on every page, then save.
Settings that change the result the most
- Background graphics: off by default, which is why dark or coloured designs come out white.
- Margins: “None” or “Minimum” for designs that should go edge to edge, “Default” for documents.
- Scale: 80-90% often prevents a wide layout from being cut on the right side.
- Layout: landscape for dashboards and wide tables.
On a phone
The same method works on mobile. In Chrome for Android, open the menu, choose Share → Print and select “Save as PDF” as the printer. In Safari on iPhone, tap Share → Print, then use the share button in the print options to save the PDF to Files. Options such as backgrounds and margins are more limited than on a computer.
Method 2: screenshot the page with html2canvas and jsPDF
html2canvas redraws the page into a canvas, and jsPDF places that image into PDF pages. The result looks very close to what you see on screen, including backgrounds and web fonts, because it ignores print CSS. The price: the PDF is a set of images, so text cannot be selected or searched, and files are bigger.
Add the two libraries to your page and call the function from a button. This snippet slices one tall capture into A4 pages:
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script>
async function savePdf() {
const el = document.querySelector('#report');
const canvas = await html2canvas(el, { scale: 2, useCORS: true });
const img = canvas.toDataURL('image/jpeg', 0.92);
const pdf = new window.jspdf.jsPDF({ unit: 'mm', format: 'a4' });
const pageW = pdf.internal.pageSize.getWidth();
const pageH = pdf.internal.pageSize.getHeight();
const imgH = canvas.height * pageW / canvas.width;
// one tall image, shifted up by one page height on each new page
for (let y = 0; y < imgH; y += pageH) {
if (y > 0) pdf.addPage();
pdf.addImage(img, 'JPEG', 0, -y, pageW, imgH);
}
pdf.save('report.pdf');
}
</script>- useCORS: true lets images from other domains appear, but only if those servers send CORS headers; otherwise they are left blank.
- scale: 2 gives sharper text at the cost of a heavier file.
- html2canvas re-implements CSS itself, so some modern features (for example oklch() colours, used by Tailwind CSS v4, and some filters) can render wrongly or fail.
- Slicing by page height can cut a line of text in two; a smarter split needs extra code.
Method 3: headless Chrome and Puppeteer for developers
If you convert many files, or need a PDF on a server, run Chrome without a window. It uses the same engine as Chrome’s print dialog, so you get real text and print CSS support, with no clicking.
One command with Chrome
Chrome can print a local file or a URL straight to PDF. Use absolute paths on Windows.
# Windows (PowerShell)
& "C:\Program Files\Google\Chrome\Application\chrome.exe" --headless --no-pdf-header-footer --print-to-pdf="C:\out\page.pdf" "C:\work\page.html"
# macOS
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless --no-pdf-header-footer --print-to-pdf=page.pdf page.htmlMore control with Puppeteer
Puppeteer (Node.js) lets you wait for the network to go idle, keep backgrounds and set the page size and margins in code.
// npm install puppeteer (downloads its own Chrome)
import puppeteer from 'puppeteer';
import { pathToFileURL } from 'node:url';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(pathToFileURL('page.html').href, { waitUntil: 'networkidle0' });
await page.pdf({
path: 'page.pdf',
format: 'A4',
printBackground: true,
margin: { top: '12mm', right: '12mm', bottom: '12mm', left: '12mm' }
});
await browser.close();- printBackground: true is the scripted version of the “Background graphics” checkbox.
- Add preferCSSPageSize: true if your stylesheet defines @page size.
- Playwright has an equivalent page.pdf() for Chromium.
Methods 1 and 2 without any setup
Most people do not want to edit the page or install Node.js. The free HTML to PDF tool wraps both browser methods in one screen. Your file is opened in a sandboxed frame inside your own browser and is never uploaded; there is no sign-up and no watermark.
- Drop one or more .html files, paste the code, or drop a .zip that contains the HTML with its images, CSS and fonts.
- Choose A4, US Letter or 16:9 slides, the orientation and the margins.
- If the page uses the Tailwind CDN or animated charts, raise the “wait N seconds” value.
- Keep the fixes on: animations frozen at their end state, scroll-reveal content shown, fixed headers shown once, full-height sections pinned to the page height, dark backgrounds kept.
- Click “Print / Save as PDF” for selectable text (method 1), or “Download PDF” for a one-click, pixel-faithful copy (method 2, text not selectable).
Add a few lines of print CSS for a cleaner PDF
Methods 1 and 3 follow the page’s print stylesheet. A short @media print block fixes most layout problems at the source: page size, margins, background colours and awkward breaks.
@page {
size: A4; /* or: letter, or A4 landscape */
margin: 12mm;
}
@media print {
/* keep background colours and images */
body {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
/* hide what makes no sense on paper */
nav, .no-print, button {
display: none !important;
}
/* avoid cutting blocks in half */
figure, img, table, tr, .card {
break-inside: avoid;
}
h1, h2, h3 {
break-after: avoid;
}
}- print-color-adjust: exact asks the browser to keep backgrounds even when the user forgets the checkbox (Chrome also needs the -webkit- prefix in older versions).
- break-inside: avoid keeps images, cards and table rows on one page when possible.
- @page size is respected by Chrome, Edge and Firefox; Safari support is more limited, so also set the paper size in the dialog.
Going further
For named pages, repeating table headers and printing link URLs, see the print CSS cheat sheet. To pick the right format, read A4 vs Letter vs 16:9 page sizes.
Common problems and quick fixes
- White page instead of a dark design: turn on background graphics or add print-color-adjust: exact.
- Wrong font: the web font had not loaded yet; wait a moment before printing, or embed the font files in a .zip.
- Empty chart: the chart was still animating; disable the animation or wait longer.
- Header repeated on every page: position: fixed elements print on each page in Chrome; hide them with @media print or use the converter’s fixed-header fix.
- Huge empty gaps: sections with height: 100vh take a whole page; set height: auto in print.
Each of these is explained in detail, with the CSS fix, in why your HTML to PDF looks broken. If your page came from an AI chat, start with ChatGPT HTML to PDF.
Privacy: where does your HTML go?
Many “online converters” upload your file to a server to render it. That is a problem for client reports, invoices or pages that contain API keys. The three methods above keep the file on your computer, and so does our in-browser converter.
One honest nuance: if the page itself loads Google Fonts, the Tailwind CDN or images from other websites, your browser fetches those resources, exactly as it does when you open the file normally. The HTML itself is not sent anywhere.
FAQ
What is the easiest free way to convert HTML to PDF?
Open the HTML file in Chrome, Edge, Firefox or Safari, press Ctrl+P or Cmd+P, choose Save as PDF and enable background graphics. It needs no software, keeps the text selectable and works offline.
Why is the text in my PDF not selectable?
The PDF was made from screenshots, for example with html2canvas and jsPDF or a one-click “download” button. Use the browser print dialog or headless Chrome instead if you need selectable, searchable text.
Why are the colours and backgrounds missing in my PDF?
Browsers skip backgrounds when printing to save ink. Tick “Background graphics” (Chrome, Edge) or “Print backgrounds” (Firefox, Safari), or add print-color-adjust: exact to the page’s CSS.
Can I convert several HTML files to PDF at once?
Yes. Headless Chrome or Puppeteer can loop over files in a script. Without code, a browser-based converter that accepts several files or a .zip lets you process them in one session.
Is it safe to convert confidential HTML online?
Only if the tool does not upload the file. Browser printing, headless Chrome and in-browser converters keep the HTML on your device; external fonts or images referenced by the page are still fetched by your browser.
Try it: free HTML to PDF converter
Runs in your browser: no upload, no sign-up, no watermark.
A free tool by Dawwerni, makers of gamified loyalty for local businesses.