Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Pass backgroundColor: null to html2canvas(), then export the returned canvas as PNG. That removes html2canvas’s fallback white paint, but it does not remove opaque CSS backgrounds from the element or its children.
const canvas = await html2canvas(element, {
backgroundColor: null
});
const pngDataUrl = canvas.toDataURL('image/png');
If the result still looks white, inspect the captured DOM’s computed backgrounds, the image format, cross-origin assets, and browser canvas-size limits.
What backgroundColor: null actually changes
html2canvas builds a canvas by rendering a DOM element. Its default canvas background is white (#ffffff). Setting backgroundColor to null tells the renderer to leave that fallback transparent when the captured DOM does not provide a background.
const element = document.querySelector('#card');
const canvas = await html2canvas(element, {
backgroundColor: null
});
document.body.appendChild(canvas);
This option affects the background supplied by html2canvas itself. It does not make an element transparent when that element, a parent, or a descendant has an opaque CSS background such as background: white or background-color: rgb(255, 255, 255). Those styles are part of the content being rendered and must be changed separately.
#1 Best Overall
Complete browser example
The following page captures a card with a transparent area around it and downloads a PNG that retains alpha transparency.
<button id="download" type="button">Download PNG</button>
<div id="card" class="card">
<h1>Transparent export</h1>
<p>The page behind this card will show through.</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/html2canvas/dist/html2canvas.min.js"></script>
<script>
const button = document.querySelector('#download');
const card = document.querySelector('#card');
button.addEventListener('click', async () => {
const canvas = await html2canvas(card, {
backgroundColor: null
});
const link = document.createElement('a');
link.download = 'transparent-card.png';
link.href = canvas.toDataURL('image/png');
link.click();
});
</script>
PNG is important because it supports an alpha channel. JPEG does not preserve transparent pixels; a JPEG export must use an opaque background. The html2canvas examples use canvas.toDataURL('image/png') for this reason.
Make the captured content transparent
Change the source CSS
If the element itself supplies the white fill, remove it before capture. For example:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
.card {
background: transparent;
}
.card .panel {
background-color: transparent;
}
Keep text, borders, shadows, and other visual styles if needed; only the declarations that paint the unwanted areas need to change. Check every descendant, because a child’s background can cover an otherwise transparent parent.
Use onclone for export-only changes
You can leave the live page unchanged and edit the cloned document that html2canvas renders. This is useful when the production UI needs a white panel but the downloaded asset should not.
Rank #2
const canvas = await html2canvas(document.querySelector('#card'), {
backgroundColor: null,
onclone: (clonedDocument) => {
const clonedCard = clonedDocument.querySelector('#card');
clonedCard.style.backgroundColor = 'transparent';
clonedCard.querySelectorAll('.export-opaque').forEach((node) => {
node.style.backgroundColor = 'transparent';
});
}
});
onclone runs against the temporary document, so these inline changes do not alter the visible page. If a stylesheet rule has higher specificity or uses !important, add an export class in the clone or adjust the rule accordingly.
Check computed styles rather than source files alone
Backgrounds can come from inherited classes, pseudo-elements, gradients, or component-library rules. In browser developer tools, inspect the captured node and its descendants, then review the Computed panel for background-color, background-image, and pseudo-elements. A white-looking result may also be a viewer displaying transparent pixels against white, so inspect the PNG over a checkerboard or dark page.
Preserve alpha when exporting
Use PNG and a binary download
For a larger image, convert the data URL to a Blob and download it. This avoids keeping a long base64 string in the link.
const canvas = await html2canvas(element, {
backgroundColor: null
});
const blob = await new Promise((resolve) => {
canvas.toBlob(resolve, 'image/png');
});
if (!blob) {
throw new Error('PNG encoding failed');
}
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'capture.png';
link.click();
URL.revokeObjectURL(url);
Do not set a white fill with ctx.fillRect() before exporting; that would intentionally make the pixels opaque. If you draw additional content yourself, preserve the canvas’s transparent initial state.
Verify that alpha exists
Place the canvas or the downloaded PNG over two contrasting backgrounds. A white preview alone cannot prove that pixels are opaque. You can also inspect a pixel programmatically:
Rank #3
const ctx = canvas.getContext('2d');
const pixel = ctx.getImageData(0, 0, 1, 1).data;
console.log({ red: pixel[0], green: pixel[1], blue: pixel[2], alpha: pixel[3] });
An alpha value of 0 means that sampled pixel is fully transparent; values between 1 and 254 are partially transparent.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsCross-origin images: CORS or a proxy
html2canvas cannot freely read every image loaded from another origin. Browser security rules can prevent a cross-origin image from being drawn into an origin-clean canvas. When the remote server sends an appropriate Access-Control-Allow-Origin header, request the image with CORS enabled:
const canvas = await html2canvas(element, {
backgroundColor: null,
useCORS: true
});
useCORS: true is not a bypass. The image host must opt in with the correct response header, and the image URL must be requested in a way the browser accepts. If you control neither server, load the asset through a same-origin proxy that adds the required headers and enforces your own security and size limits.
allowTaint is false by default. Enabling it does not make a tainted canvas readable for PNG export; a canvas that violates origin-clean rules can still fail when you call toDataURL(), toBlob(), or getImageData(). Avoid treating arbitrary remote URLs as safe proxy input, because a proxy can become a server-side request-forgery and bandwidth risk.
Capture size, viewport, and blank output
Browsers impose maximum canvas dimensions. Very tall pages, large scale factors, or wide scroll regions can exceed those limits and produce a blank, clipped, or partially rendered result. Match the render viewport to the content when appropriate:
Recommended Free Tools
const canvas = await html2canvas(element, {
backgroundColor: null,
windowWidth: element.scrollWidth,
windowHeight: element.scrollHeight
});
Use the element’s actual dimensions rather than blindly increasing them. For unusually large documents, capture smaller sections and assemble them, reduce the scale, or use a server-side screenshot workflow. A high device scale factor improves detail but increases memory use and the chance of hitting a limit.
Practical options for reliable captures
Wait for content before rendering
Call html2canvas after fonts, images, and application data are ready. For images, wait for their load or decode() promise where possible. Capturing immediately after inserting a component can produce missing assets even when transparency is configured correctly.
Choose a controlled scale
The default scale follows the device pixel ratio. Set a lower value for memory-constrained devices or a known value for reproducible output:
const canvas = await html2canvas(element, {
backgroundColor: null,
scale: 1
});
Higher values create more pixels and larger files. They do not fix a CSS background or a CORS failure.
Remember what html2canvas renders
html2canvas reconstructs a representation of the DOM in the browser; it is not a screenshot of the browser’s compositor. Content that depends on unsupported CSS, browser chrome, plugins, or cross-origin restrictions may differ from what you see on screen. Test the specific components and browsers your application supports, and pin the html2canvas version when consistent output matters.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting checklist
The exported PNG has a white rectangle
- Confirm the option is exactly
backgroundColor: null, not the string'null'. - Inspect the captured element and descendants for opaque
background-color,background, gradients, and pseudo-elements. - Use
oncloneto remove export-only backgrounds. - Open the PNG over a contrasting background to distinguish real white pixels from a white preview.
A remote image is missing
- Check whether the image is cross-origin.
- Set
useCORS: trueonly when the image server supplies a compatibleAccess-Control-Allow-Originheader. - Otherwise serve the asset through a controlled same-origin proxy.
Export throws a security or read error
A disallowed cross-origin draw can taint the canvas. Fix the image loading path rather than trying to read the tainted canvas. Do not rely on allowTaint for an export that needs toDataURL, toBlob, or pixel inspection.
The result is blank, clipped, or crashes the tab
- Reduce
scaleand capture smaller regions. - Set
windowWidthandwindowHeightto suitable scroll dimensions. - Check for browser canvas dimension limits and memory pressure.
- Wait until layout, fonts, and images have finished loading.
Or skip the browser setup
For a URL you need to capture rather than a live DOM node, ScreenshotNeo provides a single-request screenshot API. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; 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.
cURL:
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)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
See the ScreenshotNeo documentation for the full option set, including PNG, JPEG, and WebP output, transparent backgrounds, custom CSS and JavaScript, element selectors, device presets, waiting rules, cookies, headers, geolocation, PDF capture, caching, asynchronous jobs, bulk capture, signed links, and usage reporting. Its MCP server gives Claude, Cursor, and other MCP clients tools named take_screenshot, get_page_info, and capture_pdf.
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 →The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account to try it without a card.
When to use each approach
| Need | Best fit | Reason |
|---|---|---|
| Export a component already rendered in your page | html2canvas | It can render a selected DOM element and let your code alter the clone before export. |
| Capture a public URL without writing browser automation | ScreenshotNeo | One HTTP request handles consent UI and reports whether the result was billed. |
| Capture pages as part of an AI workflow | ScreenshotNeo MCP server | AI clients can call screenshot and page-information tools directly. |
| Preserve transparent pixels locally | html2canvas plus PNG | You control CSS backgrounds and the browser-side export. |
Frequently Asked Questions
Can I use JPEG for a transparent html2canvas image?
No. JPEG has no alpha channel. Export PNG or another format that supports transparency.
Does backgroundColor: null remove a white child element?
No. It only changes html2canvas’s fallback canvas background. Change the child’s CSS or use onclone.
Why does useCORS: true still fail?
The remote image server must return a compatible CORS header. The option cannot override browser origin policy.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Is a transparent result always displayed as a checkerboard?
No. Image viewers and webpages choose their own preview background. Check the alpha channel or view the image over contrasting colors.
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.

