Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Short answer: html2canvas does not take a native browser screenshot. It walks the DOM and rebuilds an image from the CSS properties it has implemented, and its official feature list labels transform as having limited support. If a rotation, scale, 3D transform, or custom transform function is missing or wrong, first verify the installed version and the element’s computed transform, then reduce the case to a minimal reproduction. You can either apply a capture-only simplified style, report a reproducible bug, or use a browser-rendered capture when pixel fidelity is essential.
What html2canvas is actually rendering
html2canvas runs in the browser and reconstructs a representation from DOM content and styles. It is not equivalent to the browser’s compositor taking a screenshot of the already-rendered page. A property that the library does not understand cannot be reproduced merely because Chrome, Firefox, or Safari displays it correctly.
The project’s FAQ explains the limitation directly: “Every CSS property must be manually implemented to render correctly, so html2canvas will never have full CSS support.” The features list therefore marks transform as Limited support, not as full CSS-transform compatibility.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteThis distinction explains several apparently contradictory symptoms:
#1 Best Overall
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
- The page looks correct in the browser, but the canvas has an unrotated or mis-scaled element.
- A simple transform works while a longer transform list does not.
- A transformed element appears in the wrong position or is clipped.
- A blank or incomplete capture is blamed on transforms even though a cross-origin image, canvas, or iframe is the real cause.
Do not treat any single successful rotate() test as proof that every 2D or 3D transform is supported. Confirm the exact package release and reproduce the specific syntax you use.
First diagnose the transform, not the screenshot
1. Record the environment
Write down the html2canvas version from your lockfile or package manifest, the browser and version, operating system, and the code that invokes html2canvas(). The repository’s current master source can differ from the released package installed in your application, so source-code behavior must not be assumed to describe every version.
2. Inspect the computed value
Inline CSS can say one thing while stylesheets, inheritance, animations, or media queries produce another. Inspect the actual target element:
Free tools Windows power users keep installed
One-click scans. No signup required.
const element = document.querySelector('#capture');
const style = getComputedStyle(element);
console.log({
transform: style.transform,
transformOrigin: style.transformOrigin,
width: style.width,
height: style.height,
position: style.position,
overflow: style.overflow
});
A computed value of none means the transform is not active on that node. A value such as matrix(a, b, c, d, tx, ty) is the browser’s resolved 2D representation. Other function names, such as a remaining rotate(), scale(), or 3D function, indicate that the browser has not reduced the value to a 2D matrix at that point.
3. Make a minimal reproduction
Copy only the failing element, the smallest required stylesheet, and one call to html2canvas into a test page. Remove frameworks, animations, unrelated overlays, web fonts, and content that is not needed to show the discrepancy. Keep the transform exactly as used in production. The project FAQ recommends a test case when a property is missing or incomplete; a small reproduction also makes version changes and workarounds safer to evaluate.
Rank #2
<div id="capture">
<div class="card">Transformed content</div>
</div>
<style>
#capture { width: 320px; height: 180px; background: #eee; }
.card { width: 120px; padding: 20px; transform: rotate(17deg) scale(1.15); background: white; }
</style>
<script>
html2canvas(document.querySelector('#capture')).then(canvas => {
document.body.appendChild(canvas);
});
</script>
What the parser source tells you
The transform parser visible in the project repository has a lookup of recognized function names. When it encounters a name without a parser, it throws an error equivalent to Attempting to parse an unsupported transform function "…". In that source, matrix() accepts six numeric values.
The same source includes a matrix3d() handler whose comment says that 3D transforms are not supported at that point. It extracts selected values from the 16-number matrix and returns a 2D representation. That is not general 3D rendering: perspective, depth, and other compositor behavior should not be expected to survive.
These observations describe the retrieved repository source, not a guarantee for every published release. Use them to form a hypothesis, then test the version actually installed. The safest broad conclusion remains the official “Limited support” label.
Practical fixes, in order of least disruption
Keep the transform and simplify its syntax
If your reproduction fails with a complex transform list, test a mathematically equivalent form that the installed parser recognizes. For example, compare a simple 2D transform with the browser’s computed matrix() value. This is a diagnostic experiment, not a promise that every matrix will render correctly. Preserve the original page and compare the output at the same viewport and device-pixel ratio.
Use a capture-only style
When the transformed geometry is not essential to the image, temporarily remove or simplify the transform, capture, and restore the live style. Always restore it in a finally block so an exception cannot leave the application visually broken.
Rank #3
- 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
async function captureWithoutTransform(selector) {
const element = document.querySelector(selector);
if (!element) throw new Error(`No element matches ${selector}`);
const original = element.style.transform;
const originalTransition = element.style.transition;
try {
element.style.transition = 'none';
element.style.transform = 'none';
// Force style calculation before cloning/rendering.
void element.offsetWidth;
return await html2canvas(element, {
backgroundColor: null
});
} finally {
element.style.transform = original;
element.style.transition = originalTransition;
}
}
captureWithoutTransform('#capture').then(canvas => {
document.querySelector('#output').replaceChildren(canvas);
});
This changes layout and visual geometry. It is suitable only when an untransformed capture is acceptable, or when you can reproduce the intended geometry with ordinary width, height, margin, and position values. If the transform controls where an element belongs, removing it can cause overlap, clipping, or a different scroll size.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Freeze animation and interaction first
An animation can make the computed transform change between inspection and capture. Pause the animation, disable transitions, wait for the next frame, and then capture. Also ensure hover, focus, and expanded-menu states are intentional; html2canvas will reconstruct the state that exists when it traverses the DOM.
async function nextPaint() {
await new Promise(requestAnimationFrame);
await new Promise(requestAnimationFrame);
}
const target = document.querySelector('#capture');
target.classList.add('capture-mode');
try {
await nextPaint();
const canvas = await html2canvas(target);
// use canvas
} finally {
target.classList.remove('capture-mode');
}
.capture-mode,
.capture-mode * {
animation: none !important;
transition: none !important;
}
Report a support gap upstream
Open an issue only after producing a small, deterministic example. Include the exact html2canvas version, browser, operating system, computed transform, minimal HTML and CSS, invocation options, expected browser appearance, and actual canvas result. Mention whether images, canvas elements, fonts, or iframes are present. This separates a parser limitation from a resource or security problem.
When the problem is not transform parsing
Cross-origin images and tainted canvases
html2canvas documents restrictions around cross-origin images and canvas content. An image may be visible in the page yet unavailable to a canvas without an appropriate cross-origin policy. Test the transformed element with solid-color boxes first; if that works, add images one at a time and check their response headers and loading strategy.
Cross-origin iframes
Content in a cross-origin iframe cannot be read like same-origin DOM. A transform applied inside that frame is not something the parent page can reliably reconstruct. Capture the frame from an environment with the required access, or expose a same-origin rendering path.
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 matchRank #4
Off-screen culling
The configuration reference describes cullOffscreen. When enabled, transformed nodes are painted conservatively for culling purposes. It does not add support for an unrecognized transform function. If an element near the viewport edge disappears, compare captures with culling behavior changed, but do not use that option as a transform parser fix.
Fonts, late content, and layout timing
Wait for the target fonts and images before capturing. A late font swap changes line wrapping and therefore the apparent result of a transform. Likewise, lazy content or a resized viewport can move the element after you inspected its computed style.
Choosing a remedy
| Approach | Visual fidelity | Runtime and cost | Main trade-off |
|---|---|---|---|
| Keep the CSS and use html2canvas | Depends on the implemented subset; not guaranteed to match browser pixels | Runs in the browser with your existing JavaScript | Unsupported functions and resource restrictions remain |
| Temporarily remove or simplify the transform | Reliable only for a deliberately simplified layout | Browser-only; small implementation change | Changes geometry and can affect the live page if restoration fails |
| Use browser-rendered capture | Best fit when exact composited pixels, perspective, or complex effects matter | Usually requires browser automation or a screenshot service | More setup, resource handling, authentication, and operational decisions |
There is no universally best replacement established by the html2canvas documentation. Decide using the required fidelity, whether a real browser is available, cross-origin and authentication needs, execution time, and whether changing the page during capture is acceptable.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
ScreenshotNeo captures the browser-rendered page through a screenshot API, so you do not have to make html2canvas understand the transform. Its clean-shot workflow accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. It also provides an MCP server for AI agents, including Claude and Cursor.
Use the same approach when the target contains perspective, nested transforms, or other compositor effects that must match what a visitor sees. The API supports PNG, JPEG, WebP, and PDF output, and includes options for full-page lazy-image loading, CSS-selector element capture, device presets, custom viewport and retina scale, CSS and JavaScript, click and wait actions, hidden selectors, request blocking, headers, cookies, user agent, authorization, timezone, geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous jobs, bulk capture, and usage reporting. Those options let you address page state and resource problems without changing production CSS.
See the ScreenshotNeo documentation for request parameters. A one-call capture looks like this:
Best Value
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(`${res.status} ${res.statusText}`);
const bytes = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));
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 the capture without a card.
Troubleshooting checklist
The transform is ignored
- Confirm the computed value is not
none. - Replace the transform temporarily with a simple 2D case.
- Check for an unsupported function error in the console.
- Verify that the package version matches the behavior you inspected in source.
The element is shifted or clipped
- Check
transform-origin, containing-block dimensions, and overflow. - Capture at a fixed viewport and device-pixel ratio.
- Test whether off-screen culling changes the result.
- Compare an untransformed capture to distinguish geometry from parser behavior.
The canvas is blank or missing images
- Capture a solid-color reproduction without external assets.
- Investigate cross-origin image and iframe restrictions separately.
- Wait for fonts, images, lazy content, and animations to settle.
- Check browser console errors and network responses.
The workaround damages the page
- Save every inline value you change.
- Disable transitions while changing styles.
- Restore in
finally, including when html2canvas rejects. - Prefer a cloned or dedicated capture layout when changing the live DOM is unsafe.
Bottom line
Assume that html2canvas may not reproduce a CSS transform exactly. Measure the computed style, reduce the case, and test the installed release rather than relying on repository master. Simplify the transform or use a capture-only layout when altered geometry is acceptable. If the image must match the browser’s composited pixels, use a browser-rendered capture method instead of treating html2canvas as a full screenshot engine.
Frequently Asked Questions
Does html2canvas support transform: rotate() or scale()?
The official feature list classifies transform as having limited support. Test the exact syntax and installed version; a result from one simple 2D transform does not establish support for all transform functions.
Can cullOffscreen add missing transform support?
No. It controls conservative painting of transformed nodes during off-screen culling. It is not documented as a parser or 3D-support switch.
Should I convert every transform to matrix()?
No. A matrix can be a useful diagnostic simplification, but compatibility still depends on the installed parser and the geometry you need. Verify the output with a minimal reproduction.
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.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →

