HTML to PDF
Turn HTML markup or a saved web page into a PDF, rendered in your browser.
About HTML to PDF
It Takes a Picture of Your HTML
Your markup is laid out in a frame of its own, walled off from this page so our styling cannot bleed into yours. The browser renders it, html2canvas photographs the result, and every page of the finished PDF is a PNG image of what got drawn.
So the text is not selectable. Ctrl+F finds nothing in the output and a screen reader gets silence. If you need a searchable text layer, your browser’s own Print to PDF makes one, or you can run the finished file through OCR PDF afterwards. Worth knowing before you spend an afternoon on the CSS rather than after.
What you get in exchange is a layout that does not move. Flexbox columns, CSS grid, gradients, rounded corners, box shadows and inline SVG land exactly where the browser put them, because the picture is taken after the layout engine has already finished. Rendering runs at twice final size, about 144 dpi. Fine on screen and on an office printer; send it to a commercial press and the pixels start to show.
When a Picture Is the Right Answer
Rasterising is a bad idea for a contract someone needs to search through. It works well when the look of the page is the point.
Internal Dashboards
Charts and status panels that only exist behind your login. Copy the rendered markup out of your element inspector and convert it here; the numbers never go into anyone else’s upload form.
Invoices Your App Already Renders
Most billing templates are HTML with a print stylesheet bolted on. Convert one straight to PDF instead of standing up a headless Chrome service just to print a document.
Campaign and Email Proofs
Newsletter markup is table-based and inline-styled, and it renders differently in every mail client. A raster proof is one version everyone in the sign-off chain sees the same way.
Bug Reports and Design Snapshots
Freeze a broken layout or a finished component exactly as it rendered and attach it to the ticket. Nobody needs to select the text on a screenshot.
Pasting Markup Is Not the Same as Opening a File
The Import .html button reads the text of that one file, and only that file. A stylesheet sitting next to it, a logo in ./images, a webfont in ./fonts: none of it follows, because a browser will not hand a web page the rest of your disk.
Relative paths are the quiet failure. Your markup is rendered here rather than where it was saved, so src="logo.png" resolves against oxygenpdf.com instead of the folder the file came from, so it fetches nothing and you get a gap. Absolute https:// URLs do load, provided the server sends CORS headers back. Servers that do not are skipped, and there is no warning either way.
Scripts never run. Markup added this way does not execute its script tags, so a single-page app saved from the browser comes out nearly blank. You saved the shell, not the render. Copy the live DOM from your element inspector and paste that instead. What travels reliably is whatever is self-contained: a style block inside the file, inline style attributes, images written as data URIs.
How It Compares
Three ways to get HTML into a PDF. This one does not win every row, and the rows it loses are the ones worth reading.
| Feature | OxygenPDF | Chrome Print to PDF | PDFCrowd |
|---|---|---|---|
| Converts markup you paste in | |||
| Output text is selectable | |||
| Renders screen styles, not the print stylesheet | |||
| Honours CSS page-break rules | |||
| Nothing leaves your device | |||
| No account or API key | |||
| Page size and margins you choose | A4 only |
What Survives, and Where Pages Break
Colours, gradients, borders, rounded corners, box shadows, opacity, CSS transforms, text shadows, tables, lists and inline SVG all come through. The renderer redraws each box itself rather than asking the operating system for a screenshot, which is why a handful of newer effects have no equivalent and get dropped without warning: filter and its blur(), mix-blend-mode, backdrop-filter, clip-path and masks.
Your markup is laid out in a viewport about 515 pixels wide, which is the A4 content width measured in CSS pixels. So responsive pages render at their narrow breakpoint, and a @media (min-width: 768px) rule never fires. If your layout only looks right above 768 pixels, it will not look right here.
The finished picture is one tall image, sliced into page-height strips at fixed intervals. The cut is arithmetic and does not care what is underneath it, so a table row or a heading can land half on one page and half on the next. CSS page-break-inside will not help; push the awkward element past the boundary with extra margin or an empty spacer. About 762 points of content fit on each page.
Your HTML Never Leaves This Tab
Every server-side converter needs your markup on its machine. Either you paste it into a form and it is uploaded, or you give it a URL and its crawler fetches the page, which for anything behind a login means handing over credentials as well. Neither is a comfortable trade for a screen full of customer names, or for an unreleased staging build.
The whole render happens in the tab you already have open: html2canvas draws your markup, pdf-lib assembles the pages, and the download comes straight out of memory. Nothing on the network carries your HTML anywhere. Close the tab and it is gone.
HTML to PDF: Frequently Asked Questions
Common questions about this tool and how it works.
Free Forever
Pro
$9 one-time