PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To capture a complete, sharp html2canvas image, size the virtual window to the element’s scroll dimensions, choose a deliberate crop, render at an appropriate pixel scale, and wait for fonts and images before calling the library. Cross-origin assets still require server permission or a same-origin proxy; no html2canvas option can bypass browser security. The workflow below covers full-page and regional captures, blurry text, missing images, complex CSS, and the limits you cannot configure away.
Use the right capture dimensions first
html2canvas renders a DOM element into a browser canvas. The visible viewport is not automatically the whole document, so a page can appear clipped even when the DOM contains more content. Set windowWidth and windowHeight to the target’s scroll dimensions when you need the complete element. Use x, y, width, and height when you intentionally want a region.
Complete element capture
This pattern captures content below the viewport and requests a white background. It also waits for fonts when the browser exposes the Font Loading API.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →await document.fonts?.ready;
const target = document.querySelector('#capture');
if (!target) throw new Error('Missing #capture element');
const canvas = await html2canvas(target, {
scale: window.devicePixelRatio,
windowWidth: target.scrollWidth,
windowHeight: target.scrollHeight,
backgroundColor: '#ffffff',
useCORS: true,
logging: true,
onclone: (clonedDoc) => {
// Capture-only changes go here.
}
});
const image = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.download = 'capture.png';
link.href = image;
link.click();
Read the dimensions after the layout has settled. If a panel uses an internal scrollbar, its scrollHeight may be larger than its client height; that is exactly the dimension you want for a full panel capture. For a horizontally scrolling region, use scrollWidth as well. Check the computed dimensions in DevTools before changing options.
#1 Best Overall
Capture a deliberate crop
Full-element output can be very large. A crop is more predictable when you know the region that matters:
const canvas = await html2canvas(document.body, {
x: 120,
y: 300,
width: 900,
height: 600,
windowWidth: document.documentElement.scrollWidth,
windowHeight: document.documentElement.scrollHeight,
scale: 2
});
The coordinates are CSS pixels in the rendered document. Keep the window dimensions large enough to include the crop; otherwise the renderer may still see a viewport-sized layout and omit content outside it.
Make text sharper without exhausting the browser
A canvas is a raster image. Blurry text normally means too few output pixels, not a font-family setting. The documented default for scale is window.devicePixelRatio; setting it explicitly makes the choice clear.
Free tools Windows power users keep installed
One-click scans. No signup required.
Choose a scale
- Device-pixel scale:
scale: window.devicePixelRatiousually matches the screen’s density. - Fixed scale: use
1for a smaller export, or2for a denser image when the target is modest in size. - Bounded scale: cap the value on high-density devices to avoid unexpectedly huge canvases, for example
Math.min(window.devicePixelRatio || 1, 2).
Doubling scale multiplies each dimension, so the pixel count rises roughly fourfold. Large full-page canvases consume more memory and can hit browser canvas-size limits. If an export fails or the tab becomes unresponsive, reduce scale, capture sections separately, or crop unused whitespace.
Rank #2
Wait for fonts and layout
Call the renderer only after web fonts, images, and late layout changes have completed. document.fonts.ready is a practical precaution, not a universal guarantee: applications that inject styles or data asynchronously must wait for those operations too. A short, targeted delay can help a page with known animation timing, but waiting for a real selector or application-ready event is more reliable.
await document.fonts?.ready;
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
const canvas = await html2canvas(document.querySelector('#capture'), {
scale: Math.min(window.devicePixelRatio || 1, 2)
});
Fix missing images and cross-origin assets
html2canvas cannot circumvent content-policy restrictions set by the browser. An image hosted on another origin must return a suitable Access-Control-Allow-Origin response header, or it must be fetched through a same-origin proxy that you control.
Direct CORS loading
Use useCORS: true only when the image server is configured for your page’s origin (or an allowed wildcard where appropriate). The browser still enforces the response header; the option does not grant permission.
const canvas = await html2canvas(target, {
useCORS: true,
imageTimeout: 15000,
logging: true
});
The documented imageTimeout default is 15,000 milliseconds. A slow image that exceeds the timeout can be omitted. Increase the timeout only when the page’s loading behavior justifies it; otherwise fix the asset or loading sequence.
Same-origin proxy
When you cannot change the image host, route the resource through a server on your own origin. The html2canvas documentation describes a proxy that accepts a ?url= query and returns the resource as a base64 data URI. Your proxy must validate destination URLs, restrict protocols and prevent server-side request forgery; never expose an unrestricted fetch endpoint.
const canvas = await html2canvas(target, {
proxy: '/image-proxy?url=',
useCORS: false
});
allowTaint is not a CORS workaround. A tainted canvas cannot be safely exported with toDataURL() or toBlob(), so enabling it can leave you with an unreadable result rather than a usable screenshot.
Use onclone for capture-only changes
The onclone callback receives the cloned document used for rendering. Modify that copy instead of the live page: replace a clock with a fixed value, reveal a collapsed section, disable an animation, or adjust print-specific styles.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →const canvas = await html2canvas(target, {
onclone: (clonedDoc) => {
clonedDoc.querySelectorAll('[data-live]').forEach(el => {
el.textContent = 'Snapshot value';
});
const style = clonedDoc.createElement('style');
style.textContent = `
*, *::before, *::after { animation: none !important; transition: none !important; }
.capture-only { display: block !important; }
`;
clonedDoc.head.appendChild(style);
}
});
This avoids flicker and prevents screenshot-specific edits from changing what users see.
Rank #4
Choose between the normal renderer and foreignObjectRendering
The default canvas renderer reconstructs supported HTML and CSS. Set foreignObjectRendering: true to try the browser’s SVG foreign-object path for complex text or CSS. Support and output vary by browser, so test the browsers you actually serve and retain the normal renderer as a fallback.
async function render(target) {
try {
return await html2canvas(target, {
foreignObjectRendering: true,
scale: window.devicePixelRatio
});
} catch (error) {
console.warn('Foreign-object render failed; using canvas renderer', error);
return html2canvas(target, {
foreignObjectRendering: false,
scale: window.devicePixelRatio
});
}
}
Do not assume that a successful render means identical output. Compare line wrapping, filters, pseudo-elements, SVGs and form controls in each target browser.
Exclude unstable or unwanted elements
Remove consent controls, toolbars, cursors or rapidly changing widgets from the clone. Add data-html2canvas-ignore to markup you own, or use ignoreElements for a rule in code.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsconst canvas = await html2canvas(target, {
ignoreElements: (element) => element.matches('.cookie-banner, .debug-toolbar')
});
Keep the predicate cheap; it runs while html2canvas walks the document. If an element is needed for layout, hide its visual content rather than removing the node and changing geometry.
Best Value
Limits you must design around
- The library runs entirely in the browser; it is not server rendering.
- Browser content-policy rules still apply to images, fonts and other external resources.
- Plugin content such as Flash or Java applets is not rendered.
- Sandboxed iframes without
allow-same-originhave important limitations. - Canvas dimensions and available memory impose practical limits on very long pages.
For a cross-origin iframe, you generally need cooperation from the framed page and appropriate embedding permissions; html2canvas cannot read arbitrary foreign DOM content.
A systematic troubleshooting order
- Verify the target: confirm it is attached to the document and that
getBoundingClientRect(),scrollWidthandscrollHeightare non-zero. - Wait for resources: inspect network failures, wait for fonts, images and SVG data, and disable animations in
onclone. - Inspect logs: enable
logging: trueand look for failed image loads or unsupported nodes. - Resolve CORS: add the correct response header or use a secure same-origin proxy; do not rely on
allowTaint. - Fix clipping: match
windowWidthandwindowHeightto scroll dimensions, then use explicit crop coordinates where appropriate. - Improve sharpness: raise
scalegradually while watching memory and canvas limits. - Try the alternate path: test
foreignObjectRenderingfor complex CSS, then compare it with the default renderer in each supported browser. - Remove interference: exclude controls or unstable nodes with
data-html2canvas-ignoreorignoreElements.
Typical symptoms and fixes
| Symptom | Likely cause | Action |
|---|---|---|
| Only the viewport appears | Window dimensions are viewport-sized | Set both window dimensions from the target’s scroll dimensions. |
| Text looks soft | Low raster scale | Use device-pixel scale or a bounded higher value; reduce capture area if memory is tight. |
| Images are blank | CORS failure, timeout or unloaded assets | Fix response headers, configure a secure proxy, wait for loading, and inspect logs. |
| Export throws a security error | Tainted canvas | Remove unauthorized cross-origin resources or serve them through permitted CORS/proxy paths. |
| Complex CSS differs | Renderer support varies | Test foreignObjectRendering and keep a normal-renderer fallback. |
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. It removes cookie banners, newsletter popups and chat widgets before capture; bot checks, blank pages, failed loads and cache hits are not billed. AI agents can use its MCP tools, including take_screenshot, get_page_info and capture_pdf. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000 shots.
One GET request returns PNG, JPEG, WebP or PDF. See the ScreenshotNeo API documentation for all options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
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}`);
Responses include X-Page-Verdict and X-Billed headers, so you can distinguish a clean billed capture from a failed or non-billable result. Create a free ScreenshotNeo account to start with 1,000 screenshots per month and no card.
Frequently Asked Questions
Can html2canvas capture an entire page automatically?
It can capture the full target when the virtual window is sized to the target’s scroll width and height; the default viewport alone is not a guarantee of full-page output.
Does increasing scale make CSS rendering more accurate?
It increases raster resolution and text sharpness, but it does not add support for CSS or remove cross-origin restrictions.
Should I always enable foreignObjectRendering?
No. It can help with some complex CSS and text, but browser support and output vary; compare it with the default renderer and retain a fallback.
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.

