Blurry html2canvas output usually means the canvas has fewer intrinsic pixels than the CSS box displaying it. Set an explicit scale, normally window.devicePixelRatio, and inspect the canvas dimensions. If the image still differs from the page, remember that html2canvas reconstructs the DOM and CSS; it does not copy the browser’s actual pixels. Unsupported CSS, cross-origin images, unfinished fonts, responsive viewport changes and canvas-size limits can all alter or invalidate the result.
What html2canvas actually captures
html2canvas walks the document, reads the styles and layout it understands, and paints a new bitmap into a canvas. It is therefore a DOM renderer, not a screen recorder. Its documentation cautions that the result is not guaranteed to be 100% accurate to the real representation because it builds the image from information available in the page.
The browser may display a CSS effect perfectly while html2canvas omits or approximates it. The project’s FAQ puts the limitation plainly: every CSS property must be implemented manually, so full CSS support is not possible. Filters, blend modes, complex shadows, pseudo-elements, some gradients, transforms, video and browser UI are common sources of differences.
First fix: give the canvas enough pixels
A canvas has an intrinsic bitmap size (canvas.width and canvas.height) and a separate CSS display size. If a 600-pixel-wide bitmap is displayed at 1,200 CSS pixels, the browser must enlarge it and text will look soft. High-density displays make this especially visible.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
window.devicePixelRatio describes the relationship between CSS pixels and physical device pixels. Use it as the normal sharpness baseline:
const canvas = await html2canvas(element, {
scale: window.devicePixelRatio,
backgroundColor: null
});
console.log({
cssWidth: element.getBoundingClientRect().width,
cssHeight: element.getBoundingClientRect().height,
bitmapWidth: canvas.width,
bitmapHeight: canvas.height
});
With a 900 CSS-pixel element and a device-pixel ratio of 2, a healthy result is approximately 1,800 intrinsic pixels wide. Do not judge sharpness from a page that later stretches the image with CSS; inspect the bitmap dimensions and export it at its native size.
Choosing a custom scale
Use a value above the device ratio only when you need a larger print or downstream asset. Every increase multiplies memory and rendering work, and very large bitmaps can hit browser limits. A practical test is to capture a small, static region at scales 1 and window.devicePixelRatio, then increase the region or scale gradually.
Why the capture differs from the preview
Unsupported or partially supported CSS
html2canvas implements CSS itself rather than asking the browser to rasterize the finished page. A property that works in Chrome or Firefox can be missing or incomplete in the library. Reduce the page to a small test case, temporarily remove filters, unusual blend modes and complex effects, and compare the simplified capture. If exact browser pixels matter, use a native browser screenshot instead.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Cross-origin images and tainted canvases
An image served from another origin needs permission for canvas use. Set useCORS: true when the image server sends an appropriate Access-Control-Allow-Origin header:
const canvas = await html2canvas(element, {
scale: window.devicePixelRatio,
useCORS: true
});
This option cannot create permission that the server does not grant. If you control neither origin, fetch the image through a same-origin proxy that adds the correct CORS headers, subject to the image owner’s terms. Check the browser console and Network panel for blocked image requests. Depending on the resource and browser, a failed CORS load may appear as a missing image or prevent export with a security error.
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
Fonts and images are not ready
Calling html2canvas immediately after changing the DOM can capture fallback fonts, unloaded images or a layout before web fonts have reflowed. Wait for fonts and image completion:
await document.fonts.ready;
const images = Array.from(document.images);
await Promise.all(images.map(img => {
if (img.complete) return Promise.resolve();
return new Promise(resolve => {
img.addEventListener('load', resolve, { once: true });
img.addEventListener('error', resolve, { once: true });
});
}));
const canvas = await html2canvas(document.querySelector('#capture'), {
scale: window.devicePixelRatio,
useCORS: true
});
Waiting does not repair a failed request. Use the documented error hook where available and fix the underlying URL, credentials or CORS response.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Viewport, scrolling and responsive layout
Media queries use the rendering window, not necessarily the dimensions you are looking at in a resized preview. Stabilize the responsive state with windowWidth and windowHeight. For a specific region, use x, y, width, height, scrollX and scrollY.
const target = document.querySelector('#capture');
const rect = target.getBoundingClientRect();
const canvas = await html2canvas(target, {
scale: window.devicePixelRatio,
windowWidth: document.documentElement.scrollWidth,
windowHeight: document.documentElement.scrollHeight,
x: rect.left + window.scrollX,
y: rect.top + window.scrollY,
width: rect.width,
height: rect.height,
scrollX: window.scrollX,
scrollY: window.scrollY
});
Use fixed values when you need repeatable output across machines. Otherwise a breakpoint, scrollbar or browser zoom level can legitimately produce a different layout.
Oversized or blank canvases
Browsers and operating systems impose implementation-dependent maximum canvas dimensions and total pixel counts. There is no single safe universal maximum. A full-page capture can therefore be blank, cropped or partially painted without a useful JavaScript exception. Match the capture window to the element’s scroll dimensions, log the resulting bitmap size, and split very tall pages into sections when necessary.
foreignObjectRendering is not a fidelity switch
foreignObjectRendering: true can use the browser’s foreign-object path where supported, but support varies and it does not guarantee parity. Test it against the exact CSS features and browsers you target.
Rank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
A complete diagnostic workflow
- Capture a small static element. If it is sharp, expand the region in stages; a failure that appears only at larger sizes points to resources or canvas limits.
- Log both dimensions. Compare the element’s CSS width and height with
canvas.widthandcanvas.height. A low intrinsic-to-CSS ratio explains softness. - Set
scaleexplicitly. Compare1withwindow.devicePixelRatio; avoid stretching a low-resolution result in CSS. - Wait for resources. Await
document.fonts.readyand image completion before capture. - Inspect Network and Console. Look for CORS failures, 404 responses, blocked fonts and authentication redirects.
- Freeze the viewport. Supply
windowWidthandwindowHeightthat represent the intended responsive layout. - Isolate CSS. Remove unsupported effects and compare a minimal reproduction before changing many options at once.
Reusable capture code
This example waits for assets, captures an element at device-pixel density and downloads a PNG without enlarging it in CSS:
import html2canvas from 'html2canvas';
async function capture(selector) {
const element = document.querySelector(selector);
if (!element) throw new Error(`No element found for ${selector}`);
await document.fonts.ready;
await Promise.all(Array.from(document.images).map(img => {
if (img.complete) return Promise.resolve();
return new Promise(resolve => {
img.addEventListener('load', resolve, { once: true });
img.addEventListener('error', resolve, { once: true });
});
}));
const canvas = await html2canvas(element, {
scale: window.devicePixelRatio,
useCORS: true,
backgroundColor: null,
windowWidth: document.documentElement.scrollWidth,
windowHeight: document.documentElement.scrollHeight
});
console.log(`${canvas.width} × ${canvas.height} intrinsic pixels`);
const link = document.createElement('a');
link.download = 'capture.png';
link.href = canvas.toDataURL('image/png');
link.click();
return canvas;
}
capture('#capture').catch(console.error);
When another capture method is the better fit
| Requirement | html2canvas | Native or headless browser capture |
|---|---|---|
| Exact browser-rendered pixels | Not guaranteed; reconstructs DOM and CSS | Strong fit because the browser paints the page |
| CSS and font coverage | Limited to implemented features and loaded resources | Uses the browser’s layout and rendering engine |
| Cross-origin handling | Requires CORS or a permitted proxy | Browser context can load resources under configured permissions |
| Very large pages | Subject to canvas dimensions and memory | Still needs memory planning, but avoids one giant client canvas |
| Execution | In the page’s client browser | Extension API or server-side browser process |
| Operational complexity | Small client-side dependency | Extension permissions or browser infrastructure |
For browser extensions, the official html2canvas FAQ recommends native extension screenshot APIs because they are more reliable and do not have canvas-size limits. For server-side generation, it points to Puppeteer or Playwright, which drive a real browser instead of reimplementing CSS in a client canvas.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup 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.
One GET request returns PNG, JPEG, WebP or PDF. The same service supports full-page lazy-image loading, CSS-selector element capture, dark mode, 12 device presets or custom viewports, retina scale, custom CSS and JavaScript, clicks, waits, blocking rules, headers, cookies, user agents, authorization, timezone, geolocation, transparency, resizing, TTL caching, signed image links, asynchronous webhooks, up to 100 URLs per bulk call, usage reporting and an OpenAPI specification. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsUsing the ScreenshotNeo documentation, a minimal request is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
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)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan. Create a free ScreenshotNeo account to try it.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common failures and precise fixes
“The image is blurry only after display”
The bitmap is being enlarged. Export at native dimensions, set scale: window.devicePixelRatio, and remove CSS that sets a larger rendered width than the intrinsic image.
Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
“Images are missing”
Confirm the image request succeeds, enable useCORS, and verify the origin sends an appropriate CORS header. Otherwise use a permitted same-origin proxy.
“Text changes between preview and capture”
Capture after document.fonts.ready. Check that the font response is successful and that the same viewport and zoom are used.
“The bottom of a page is cut off”
Provide the document’s scroll dimensions through windowWidth and windowHeight, set an explicit region, and split extremely tall output into multiple captures.
“The result is blank”
Reduce the region, inspect failed resources and CORS errors, and compare the output dimensions with browser canvas limits. A blank result can occur even when no exception is thrown.
“A CSS effect disappears”
Assume a renderer-coverage limitation. Create a minimal reproduction, remove or replace the unsupported effect, or switch to native extension capture or a real browser service.
Free tools Windows power users keep installed
One-click scans. No signup required.
FAQ
Does increasing scale fix visual differences?
No. Scale increases pixel density and can make edges sharper; it cannot add support for CSS that html2canvas does not implement or repair missing resources.
Best Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
Can html2canvas capture a cross-origin page?
It can capture permitted resources when CORS is configured, but it cannot bypass another server’s access policy. Use a compliant proxy or a browser-based capture method.
Should I always use foreignObjectRendering?
No. It is browser-dependent and must be tested with the page’s actual CSS. It is an option, not a universal accuracy mode.
Frequently Asked Questions
Does increasing scale fix visual differences?
No. Scale increases pixel density and can make edges sharper; it cannot add support for CSS that html2canvas does not implement or repair missing resources.
Can html2canvas capture a cross-origin page?
It can capture permitted resources when CORS is configured, but it cannot bypass another server’s access policy. Use a compliant proxy or a browser-based capture method.
Should I always use foreignObjectRendering?
No. It is browser-dependent and must be tested with the page’s actual CSS. It is an option, not a universal accuracy mode.
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.

