Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →To turn a rendered <div> into a downloadable image in a normal web page, use @html2canvas/html2canvas: select the element, await the returned canvas, and export it with toDataURL(). This is a DOM-to-canvas reconstruction rather than a photograph of browser pixels, so unsupported CSS, cross-origin images, and cross-origin iframes can change the result. If you need a true browser-rendered capture on a server, use browser automation instead.
Choose the capture method first
“Screenshot” describes two different jobs. An in-page library such as html2canvas reads an element’s DOM and styles, then paints an approximation into a new canvas. It does not invoke the browser’s own screenshot pipeline. That makes it convenient for cards, invoices, charts, and user-generated panels, but fidelity depends on the CSS and assets it can read.
A real browser capture renders a page in an actual browser process and records its painted output. That is the better model for server-side jobs, complex CSS, or pages you do not control. A browser extension that needs the current tab should use the browser’s native tab-capture APIs instead; those APIs are scoped to a visible tab, not an arbitrary element in another page.
Capture a div in the browser with html2canvas
Install the package
For a bundled application, install the maintained package:
#1 Best Overall
npm install @html2canvas/html2canvas
Then import it in your client-side JavaScript. You can also load a built release in a page, provided the script is available before your capture code runs.
Minimal runnable example
import html2canvas from '@html2canvas/html2canvas';
const element = document.querySelector('#capture');
if (!element) throw new Error('Capture target not found');
const canvas = await html2canvas(element);
document.body.appendChild(canvas); // optional preview
The function is asynchronous because images, fonts, and the cloned document may still need to be processed. Call it after the element is rendered and populated, not immediately before your framework has committed its changes.
Add a download button
import html2canvas from '@html2canvas/html2canvas';
const button = document.querySelector('#download');
button.addEventListener('click', async () => {
const element = document.querySelector('#capture');
if (!element) throw new Error('Capture target not found');
const canvas = await html2canvas(element);
const link = document.createElement('a');
link.download = 'screenshot.png';
link.href = canvas.toDataURL('image/png');
link.click();
});
A complete minimal markup example is:
<button id="download" type="button">Download PNG</button>
<div id="capture" class="card">
<h2>Quarterly result</h2>
<p>Revenue increased 18%.</p>
</div>
Keep the export format in the MIME type and filename consistent. PNG is lossless and preserves text and transparency. JPEG is smaller for photographic content but has no transparency and introduces compression artifacts. WebP can be a useful compromise where your consumers support it.
Control the captured bounds and resolution
You can crop the source area and increase pixel density with the options documented by the project:
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
const element = document.querySelector('#capture');
const rect = element.getBoundingClientRect();
const canvas = await html2canvas(element, {
x: 0,
y: 0,
width: rect.width,
height: rect.height,
scale: window.devicePixelRatio
});
const png = canvas.toDataURL('image/png');
x, y, width, and height alter output bounds. scale changes the number of output pixels; using the device-pixel ratio usually makes text sharper on high-density displays, while increasing memory use. These settings do not add support for CSS that the renderer cannot reconstruct.
Prepare the element for a reliable export
Wait for layout, fonts, and images
Capture after the final layout is visible. In an application, wait for the state update that inserts the content, and wait for critical images or fonts before calling html2canvas. A fixed capture width is often more reproducible than a responsive card whose dimensions change during export.
Hide controls and transient UI
Add a capture-only class or use a wrapper so buttons, hover states, caret indicators, and animations are excluded. Pause animations and set a deterministic theme before capture. If the element is inside a scroll container, ensure the content you need is laid out within the selected element; capturing a clipped viewport does not automatically create an unlimited document image.
Use supported CSS deliberately
html2canvas implements a subset of CSS. Gradients, filters, blend modes, advanced transforms, pseudo-elements, and other features can differ from the browser’s painted result. Check the project’s current supported-property list and test the exact browser and stylesheet combination you ship.
Recommended Free Tools
Cross-origin images, canvases, and iframes
Remote images
Browser security controls whether image pixels may be read back from a canvas. If an image is served by another origin, the server must provide suitable CORS headers. You may try:
const canvas = await html2canvas(element, { useCORS: true });
useCORS requests CORS-enabled loading; it cannot override a server that denies it. Configure the image server with an appropriate Access-Control-Allow-Origin policy, or serve the asset from the same origin.
Already-tainted canvases
If the target contains a canvas that previously drew cross-origin pixels without permission, reading the new canvas can fail with a security exception. Fix the original asset policy or omit that content; JavaScript cannot remove the browser’s taint after the fact.
Cross-origin iframes
An iframe from another origin is not readable as same-origin DOM. html2canvas cannot inspect and reconstruct its internal content. Capture the framed application from its own origin, arrange a permitted message-based export, or use a browser-level capture where you control the page and permissions.
Rank #4
When html2canvas is the wrong tool
Server-side screenshots
html2canvas is a browser library. For Node.js or another server runtime, launch a real browser with an automation framework such as Puppeteer or Playwright, navigate to the page, wait for it to settle, and capture the page or element. This records browser output rather than relying on a DOM reconstruction and is suitable for scheduled jobs and pages unavailable to the end user’s browser.
Browser extensions
If an extension needs a screenshot of the active tab, use the native screenshot APIs described in the browser extension documentation. They capture a tab under extension permissions; they are not a general way to read a cross-origin iframe or arbitrary hidden DOM node.
Very large elements
Canvas maximum dimensions and total areas vary by browser, operating system, and hardware. Huge elements can produce a blank or partial canvas, or exhaust memory. Capture smaller sections, reduce scale, or use a browser-level or server-side workflow. Do not rely on one fixed “maximum canvas size” for every environment.
Troubleshooting checklist
The target is missing
- Verify the selector and check that
querySelectorreturns an element. - Run capture after the component has mounted and after conditional content is present.
- Check shadow DOM boundaries: a selector in the light DOM cannot select an element inside a shadow root unless you obtain that root explicitly.
The image is blank or incomplete
- Wait for images and fonts, and inspect the browser console for load failures.
- Reduce the element size or
scaleif the canvas is unusually large. - Check whether an animation, lazy-loaded section, or scroll container is still changing layout.
Images disappear or export throws a security error
- Confirm the image is same-origin or served with CORS headers.
- Use
useCORS: trueonly when the remote server permits the request. - Remove or replace a pre-tainted canvas and remember that cross-origin iframe contents remain inaccessible.
The styling does not match
- Compare the CSS against the library’s supported feature list.
- Replace unsupported effects with simpler styles for the export variant.
- Capture only after web fonts have loaded and after the final theme class is applied.
The download is empty or has the wrong extension
- Ensure the canvas has non-zero dimensions before calling
toDataURL. - Use a matching MIME type and filename, and check browser download restrictions when the call occurs outside a user gesture.
Performance, fidelity, and deployment decisions
| Requirement | Best fit | Reason |
|---|---|---|
| One visible card in a normal web app | html2canvas | No server is required; the element is selected directly. |
| Pixel accuracy for complex CSS | Real browser capture | Records browser-painted output instead of reconstructing supported DOM and styles. |
| Scheduled or API-driven captures | Puppeteer, Playwright, or a screenshot API | Runs outside the user’s tab and can standardize viewport and waiting. |
| Current browser tab in an extension | Native tab screenshot API | Its permission and scope match a visible tab. |
For client-side capture, memory use grows with pixel area and scale. Avoid capturing on every keystroke; debounce requests and release temporary canvases when finished. For server workflows, reuse browser processes where safe, set explicit timeouts, and wait for a selector, network idle state, or known application signal rather than sleeping for an arbitrary interval.
Best Value
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server when you need a repeatable remote capture rather than code running in the page. A single GET request returns PNG, JPEG, WebP, or PDF. It can capture a CSS-selected element, wait for a selector or network idle, load lazy images, apply custom CSS or JavaScript, set viewport and device options, and run asynchronous or bulk jobs.
Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers. The MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
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 authentication, element options, formats, and response handling. If you want to try it, sign up free: the Free plan includes 1,000 screenshots per month with no card, and paid plans start at $5 for 3,000 shots.
FAQ
Does html2canvas take a real screenshot?
No. It reconstructs a canvas from DOM and style information, so the result can differ from browser-painted pixels.
Can it capture a cross-origin iframe?
Not by reading the iframe’s DOM. Same-origin policy prevents that access unless the content is captured through a workflow that controls the framed origin.
Is html2canvas suitable for Node.js?
It is intended for browser code. Use Puppeteer, Playwright, or a screenshot service for server-side rendering.
Why does a high-resolution export use so much memory?
Canvas memory rises with pixel area, and the scale option multiplies that area. Lower the scale or split a very large element into sections.
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.




