CSS backgrounds appear in the browser but disappear from an html2canvas export for two main reasons: the declaration or value is not implemented by your installed release, or the image cannot be read under browser origin rules. The reliable workflow is to use a supported background value, make the asset readable (same origin, CORS, or a proxy), render the correct element, and then serialize the returned canvas yourself. html2canvas creates a canvas representation from DOM and CSS; it does not take a native browser screenshot.
What html2canvas actually renders
When you call html2canvas(element), the library clones the document, reads DOM and computed styles, loads eligible assets, and paints a new canvas. It does not ask the browser for the pixels already displayed on screen. Consequently, a background can be visible in the live page yet absent from the export if html2canvas does not understand that CSS form, cannot fetch the image, or never includes the element in its render target.
The project documents this limitation directly: it can render correctly only the properties it understands, and many CSS properties do not work. Treat the result as a DOM/CSS reconstruction, not a photographic screenshot of every browser feature.
Use a background syntax html2canvas supports
The official feature list includes background-image values using url(), linear-gradient(), and radial-gradient(). It also lists background-origin, background-position, and background-size. Keep the declaration explicit while diagnosing:
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 →Scan for outdated or missing drivers - takes under a minuteDriver Scan →#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
.card {
background-image: url("/images/card-art.png");
background-position: center;
background-size: cover;
background-origin: padding-box;
background-repeat: no-repeat;
}
Set the image on an element inside the node passed to html2canvas. A background on an ancestor outside that node is not part of the cloned render tree. Likewise, a pseudo-element or an overlay can be missed if your selector or layout excludes it.
Values that need special caution
The feature list names background-blend-mode and repeating-linear-gradient() as unsupported. If your design depends on either, simplify the cloned version to a supported color, URL, or ordinary gradient. Do not assume that a declaration accepted by the browser will be reproduced by the library.
.export-copy .hero {
/* A simple fallback for the cloned export */
background-image: url("/images/hero-flat.jpg");
background-color: #172033;
}
You can apply such a fallback only to the cloned document with onclone, leaving the live page unchanged.
Make the image readable under browser security rules
Same-origin images
A relative URL such as /images/card-art.png is normally same origin when the page and image use the same scheme, host, and port. Confirm in the browser’s Network panel that the request succeeds before calling html2canvas. A 404, redirect to an authentication page, or a response that arrives after the render timeout can still produce a missing background.
Cross-origin images with CORS
For an image hosted on another origin, that server must permit the browser request with an appropriate Access-Control-Allow-Origin response. Enable CORS loading in html2canvas:
html2canvas(document.querySelector('#invoice'), {
useCORS: true
}).then(canvas => {
document.querySelector('#download').href = canvas.toDataURL('image/png');
});
useCORS defaults to false, so setting it explicitly makes your intent clear. The remote server still has to send valid CORS headers; this option cannot grant permission that the server did not provide.
Cross-origin images through a proxy
If you do not control the image host or it cannot send CORS headers, configure a proxy that fetches the asset and serves it from an origin your page can use:
Rank #2
html2canvas(document.querySelector('#invoice'), {
proxy: 'https://your.example.com/html2canvas-proxy'
});
The proxy must be designed for this purpose: validate requested URLs, restrict destinations to avoid server-side request forgery, return the image bytes with a suitable content type, and handle redirects and errors. The proxy option defaults to no proxy.
Recommended Free Tools
Why allowTaint is not a download fix
allowTaint: true changes whether html2canvas may draw content that would taint the canvas. It does not make that canvas readable. A tainted canvas cannot be exported with toDataURL(), toBlob(), or similar readback APIs. With the default allowTaint: false, html2canvas avoids drawing an image that would taint the canvas, which is usually the more useful behavior for downloads.
A complete browser download example
This example waits for a user click, renders the element, and downloads a PNG. It uses a same-origin background; add useCORS or proxy when your asset is cross-origin.
<article id="ticket" class="ticket">
<h1>Conference ticket</h1>
<p>Admit one</p>
</article>
<button id="download-ticket" type="button">Download PNG</button>
<style>
.ticket {
width: 720px;
min-height: 360px;
padding: 48px;
color: white;
background-color: #18243a;
background-image: url('/images/ticket-texture.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
</style>
<script type="module">
import html2canvas from 'html2canvas';
const target = document.querySelector('#ticket');
document.querySelector('#download-ticket').addEventListener('click', async () => {
try {
const canvas = await html2canvas(target, {
useCORS: true,
imageTimeout: 15000,
backgroundColor: null,
scale: window.devicePixelRatio || 1
});
canvas.toBlob(blob => {
if (!blob) throw new Error('Canvas could not be serialized');
const link = document.createElement('a');
link.download = 'ticket.png';
link.href = URL.createObjectURL(blob);
link.click();
URL.revokeObjectURL(link.href);
}, 'image/png');
} catch (error) {
console.error('html2canvas export failed', error);
alert('The image could not be exported. Check the console and Network panel.');
}
});
</script>
The official setup returns a canvas from a promise. The download is application code that runs after that promise resolves; html2canvas does not supply a download button or file name.
Transparent versus solid output
backgroundColor defaults to white when the DOM does not specify a background. Set it to null when you need transparency, as in the example. This controls the canvas backdrop; it does not repair a missing CSS image.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Changing only the cloned document
Use onclone for export-only adjustments. The callback receives the cloned document, so you can add a class, wait-independent fallback, or explicit style without changing the visible page:
const canvas = await html2canvas(target, {
onclone: clonedDocument => {
const copy = clonedDocument.querySelector('#ticket');
copy.classList.add('export-copy');
copy.style.backgroundImage = 'url("/images/ticket-flat.jpg")';
}
});
Check the callback API against the version installed in your project and the current configuration reference before relying on version-specific behavior.
Rank #3
Large elements, timing, and browser limits
Wait for the asset and layout
Call html2canvas after the target is in the DOM and its dimensions are final. If the background is inserted by JavaScript, await that operation first. The default imageTimeout is 15,000 milliseconds; increase it for a legitimately slow asset or set it to 0 only when you deliberately want no timeout and can tolerate a stalled export.
Capture the full scroll area
For a tall element, the FAQ recommends matching windowWidth and windowHeight to its scroll dimensions:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
const width = target.scrollWidth;
const height = target.scrollHeight;
const canvas = await html2canvas(target, {
windowWidth: width,
windowHeight: height
});
This avoids a viewport-sized clone clipping content, but it does not remove canvas-size limits. Maximum dimensions vary by browser, operating system, and hardware. Very large exports may fail, consume substantial memory, or produce a blank canvas; split the document into sections or reduce scale when that happens.
Control pixel density
scale defaults to the device pixel ratio in common setups. A high-DPI display can therefore create a much larger canvas than expected. Lower it for reliability and memory usage, or raise it only when the output needs additional detail.
Systematic troubleshooting
Work through these checks in order rather than changing several options at once.
The background is completely absent
- Inspect the target element in DevTools and verify the computed
background-imageis notnone. - Confirm the element is inside the node passed to html2canvas and is not hidden, detached, or covered by an export-only layout rule.
- Open the image URL directly and check the Network panel for 404, 403, redirect, or blocked-request errors.
- Replace the image temporarily with a
linear-gradient(). If the gradient appears, the issue is asset loading or origin policy rather than target selection.
The image works locally but not in production
Check the production image origin, HTTPS scheme, redirects, and CORS response headers. A development proxy or same-origin path can hide a production cross-origin problem. Set useCORS: true only when the server is configured to answer the request; otherwise use a controlled proxy.
The canvas throws a security error on export
This indicates a tainted canvas. Remove allowTaint: true, then make every image same-origin, CORS-enabled, or proxy-served. You cannot read a tainted canvas simply by enabling another html2canvas flag.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Only part of the CSS effect appears
Reduce the declaration to documented forms: a URL, ordinary linear or radial gradient, position, size, and origin. Unsupported blending or repeating gradients may be skipped. Use onclone to provide a simpler export style.
The export times out or is blank
- Look for a request that remains pending until the 15-second default timeout.
- Increase
imageTimeoutfor slow but valid assets, or fix the server response. - Check console messages for CORS, content-policy, decoding, and canvas-size errors.
- Reduce the target dimensions or
scaleif the browser hits a canvas limit.
The page is clipped
Render the actual target rather than a viewport wrapper, and set windowWidth and windowHeight from scrollWidth and scrollHeight. For extremely long pages, capture logical sections separately and combine them in application code.
Choosing an approach for the image source
| Image situation | What to configure | Deployment trade-off | Canvas readback |
|---|---|---|---|
| Same origin | Use a relative or same-origin URL; verify the request succeeds | Lowest complexity; you control the asset host | Normally readable |
| Cross origin with server CORS | useCORS: true and correct Access-Control-Allow-Origin |
Requires configuration on the image server | Readable when headers and request mode are correct |
| Cross origin without CORS | Serve through a controlled proxy |
Additional service, validation, caching, and security work | Readable when the proxy returns the asset from an allowed origin |
Cross origin with allowTaint: true |
Not an export strategy | Does not solve browser readback restrictions | Not readable once tainted |
There is no universal CSS-fidelity switch. If the required visual depends on unsupported properties, simplify the cloned DOM or choose a capture method that renders through a real browser rather than relying on html2canvas’s implemented property set.
Or skip the browser setup
For server-side or automated captures, ScreenshotNeo provides a website screenshot API and MCP server. One request returns PNG, JPEG, WebP, or PDF. It accepts the page like a visitor before capture, removing 60+ known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status.
Here is the one-call cURL form (the target URL is adapted to this example):
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 all options, including CSS selectors, lazy-loaded full pages, device presets and viewports, retina scale, PDF settings, custom CSS and JavaScript, click actions, waiting for selectors or network idle, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous jobs, webhooks, bulk capture, usage, and the OpenAPI specification. It also accepts parameter names used by other screenshot APIs, which can simplify migration.
An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients, so an AI agent can perform captures without you wiring a browser. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to get started.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC 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 & 11Best Value
FAQ
Does html2canvas download a file by itself?
No. It resolves with a canvas. Your code must call toBlob() or toDataURL() and create a download link or upload the bytes.
Can I use a CSS variable for the background URL?
The browser must resolve the variable to a supported computed background value in the cloned document. If it does not, set an explicit fallback in onclone and verify the computed style there.
Why does a background color export while the image does not?
Colors are local style data, whereas the image requires an additional network request and must pass origin and decoding checks. A successful color export does not prove the image request is usable.
Frequently Asked Questions
Does html2canvas download a file by itself?
No. It resolves with a canvas. Your code must call toBlob() or toDataURL() and create a download link or upload the bytes.
Free tools Windows power users keep installed
One-click scans. No signup required.
Can I use a CSS variable for the background URL?
The browser must resolve the variable to a supported computed background value in the cloned document. If it does not, set an explicit fallback in onclone and verify the computed style there.
Why does a background color export while the image does not?
Colors are local style data, whereas the image requires an additional network request and must pass origin and decoding checks. A successful color export does not prove the image request is usable.
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.

