HTML to Image — Export HTML as PNG, JPG, or WebP
Paste HTML and CSS, preview it live, and export a PNG, JPG, or WebP at any dimensions. Rendered with html2canvas entirely in your browser — nothing is uploaded.
PNG is lossless, so the slider sets the render scale (supersampling) instead — higher means sharper text and a larger file.
Preview
It repaints your HTML, it does not screenshot it
The mental model that trips people up is thinking this tool takes a screenshot. It does not, and the distinction drives all 5 sections below. There is no browser screenshot API a web page is allowed to call on arbitrary markup, so instead the tool uses html2canvas version 1.4.1, a roughly 7,830-line library that walks your Hypertext Markup Language through the Document Object Model node by node and re-draws every element — backgrounds, borders, text runs, gradients, box shadows — onto an HTML5 canvas by reimplementing a large slice of the CSS 2.1 layout and paint rules in JavaScript. A 1200x630 card is not photographed; its 756,000 pixels (1200 x 630) are recomputed 1 element at a time, then encoded. The output is a real raster image, a grid of 24-bit or 32-bit pixels, exported through the canvas toBlobcall in 1 of the 3 formats you pick: PNG, JPG, or WebP.
That architecture explains almost every quirk below. Because html2canvas is re-implementing CSS rather than using the browser's own renderer, anything it has not implemented, or anything it cannot read for security reasons, simply will not appear. Knowing that the image is reconstructed, not captured, is the single most useful thing to understand before you paste a complex layout and wonder why one piece came out wrong.
The server-side alternative is heavier by orders of magnitude. Tools built on Puppeteer or Playwright boot a full 300 MB headless Chromium, load the page, and grab a true screenshot — pixel-perfect, because it is the real Blink engine, but it needs a Node.js process of 50 to 150 MB, 1 to 3 seconds of cold start, and your markup travelling to that server over Hypertext Transfer Protocol. This tool trades that fidelity for 0 uploads and a render that is usually well under 1 second for a 1200x630 card: no binary to install, no account, no queue, 0 bytes of markup leaving your machine. For a static card, banner, or code snippet the difference in output is usually invisible; for a page leaning on unusual CSS 3 features — backdrop-filter, CSS grid subgrid, or the newer color functions — it can matter, which is the honest trade-off to weigh between the 2 approaches.
The quality slider means two different things
This is the tool's central confusion, and it is worth stating plainly. When the format is JPG or WebP, the slider is a normal compression control from 50% to 100%: at 60% a 1200x630 card lands around 43 KB, at 80% near 90 KB, at 92% near 160 KB, at 100% past 300 KB — exactly the curve you expect from a lossy format. When the format is PNG, that same slider does something else entirely, because PNG is lossless and has no quality dial to turn. Instead the slider drives the render scale: the tool computes a supersampling factor of 1 + quality × 2 (a range of 1.5x at 25% up to 3.0x at 100%, clamped to the 1x–3x band), so 50% renders at 2.0x, 75% at 2.5x, 92% at 2.84x, and 100% at 3.0x. A nominal 1200x630 PNG at 92% is therefore drawn at about 3408x1789 real pixels — 6.1 million pixels, 8x the 756,000 of the nominal size — which is why it can weigh 5 MB. The scale is capped at 3.0x, so the largest a 1200x630 PNG reaches is 3600x1890, about 6.8 million pixels.
That is not a bug, it is the right trade for PNG: sharp text on a 2x or 3x Retina display (2 to 3 device pixels per CSS pixel), and clean edges if you print the card at 300 DPI. But it surprises people who slide PNG down to 50% expecting a smaller file and instead get a still-multi-megabyte image at 2x. The label above the slider changes wording to reflect this — it reads Scale (2.0x to 3.0x) for PNG and Quality (50% to 100%) for JPG and WebP — but if you want a genuinely small file, the answer is always to switch format, not to drag the PNG slider. A JPG at 80% is often 100x smaller than the equivalent PNG — 43 KB against 5 MB in the measured example above.
Why external fonts and images come out blank
The most common disappointing result is a card that previews perfectly but exports with the wrong font, a missing logo, or an empty box where an image should be. The cause is always the same: html2canvas can only paint resources the browser has already fetched and is allowed to read. A <link>to Google Fonts may not have finished loading within the 5-second window, or the font's Cross Origin Resource Sharing rules may block the canvas from reading it. A remote background-image or <img>from another domain without the right CORS headers taints the canvas — a browser security rule dating to the 2011 canvas spec — and the export throws, at which point, after all 8 paths fail, the tool surfaces the message "Browser blocked export due to external assets." The fix is to make every asset local to the markup: use system fonts, or embed fonts and images as data: URIs (Base64) directly in the CSS so nothing has to be fetched at render time. Base64 inflates a payload by about 33% (4 characters encode every 3 bytes), but 0 network requests means 0 blank boxes.
Two other limits are worth stating outright. Inline <script>tags and every inline on* event handler (onclick, onload, onerror, and the other 60-plus) are stripped by 3 regex passes before rendering, so anything driven by JavaScript will not run or appear — this tool renders static markup, not live apps. And each side is clamped between 1 and 4000 pixels, so the largest single export is 4000x4000 (16 million pixels, roughly 64 MB uncompressed in RAM at 4 bytes each); taller documents are what the sibling paged renderer is for.
The capture pipeline, and its fallbacks
Reliability here comes from not trusting a single rendering path. The tool loads your sanitised markup into a hidden, off-screen iframe, then waits for the document to settle — it awaits document.fonts.ready, waits for every <img> to finish (with a 5-second, 5000-millisecond per-image timeout), and lets 2 animation frames pass (about 33 ms at 60 Hz) so layout is stable. Only then does it call html2canvas, under a 12000-millisecond overall render timeout and a 15000-millisecond image timeout. It attempts up to 7 distinct capture configurations in sequence — varying the transport (iframe srcdoc versus document.write), the capture target (the whole documentElement versus just body), the experimental foreignObject mode on or off, and the scale (the full 2.0x to 3.0x factor versus a safe 1x) — because different browsers and different markup succeed under different combinations. That is 7 tries plus 1 SVG fallback, 8 paths in all.
If all 7 attempts fail, there is one last resort: wrapping the markup in an SVG <foreignObject>, serialising it, loading it as an image, and drawing that to the canvas. This SVG path is the genuine fallback, not the primary engine — a detail worth correcting because it is the reverse of how many descriptions of this tool read. JPG export adds one more step: since JPG has no alpha channel (0 transparency, versus PNG and WebP's 8-bit 256 levels), the tool first fills a fresh canvas with your chosen background colour, then draws the render on top, so transparent regions become that colour instead of the default black (RGB 0,0,0).
Quick reference
- Engine: html2canvas 1.4.1 (Document Object Model repaint), SVG foreignObject as the 8th, last-resort path.
- Formats: 3 total — PNG (lossless), JPG (smallest, no alpha), WebP (compressed, alpha).
- PNG slider: render scale = 1 + quality x 2, so 50% = 2.0x, 92% = 2.84x, 100% = 3.0x supersampling.
- JPG/WebP slider: compression 50% to 100% at a fixed 2x scale.
- Dimensions: 1 to 4000 px per side; Open Graph and Twitter cards use 1200x630.
- Measured sizes: that card is about 5 MB as PNG at 92%, about 43 KB as JPG at 60% — a 116x gap.
- Cascading Style Sheets: inline styles and <style> blocks only; embed fonts and images as data URIs (Base64, +33%).
- Stripped: <script> tags and inline on* handlers, before rendering.
- Stability wait: document.fonts.ready + image load (5000 ms each) + 2 animation frames; 12s render cap.
- Privacy: 100% in-browser; the markup is never uploaded.
How to Use
Paste your HTML markup — keep all CSS inline or in a <style> block.
Set the width, height, and background colour in pixels.
Watch the live preview panel render as you type.
Pick a format: PNG (lossless), JPG, or WebP.
Click Convert to Image and download the file at the size shown.
Features
Common Questions
About HTML to Image
Paste HTML with inline CSS, watch it render in a live preview, and export it as a PNG, JPG, or WebP at any dimensions up to 4000px. Rendered with html2canvas (which repaints the DOM onto a canvas, not a screenshot), so inline styles work but external fonts and cross-origin images must be embedded as data URIs. The PNG slider controls render scale (up to 3x supersampling); the JPG and WebP slider controls compression. Ideal for Open Graph social cards at 1200x630. Runs entirely in your browser — the markup is never uploaded.
Also known as: webpage to image, html to png, screenshot html, render html as image, html to jpg, html to webp, html2canvas online, html to social card, code to image.
Processing Note
HTML to Image runs in your browser, so the input you enter is processed locally on this page and is not uploaded to a ToolMintX account.
Tool Limits
Image tools can optimize and transform files, but source quality still matters. Blurry, over-compressed, or badly lit images may need a better original before editing.
Explore More
Image Background Remover
Remove image backgrounds with an AI model that runs in your browser.
Client-sideAI Image Upscaler and Enhancer
Upscale and enhance images with AI, right in your browser.
Client-sideImage Compressor
Compress JPG, PNG, and WebP to reduce file size, with a quality slider and a live before/after readout.
Client-sideImage Metadata Viewer and Remover
View hidden EXIF, GPS, XMP, PNG, and WebP metadata, then download a cleaned image copy.
Client-side