First determine what is being cut off. If the entire screenshot stops at an edge, the canvas or capture window is too small (or has exceeded a browser canvas limit). If the canvas is complete but letters or lines are clipped, the cause is usually layout, overflow, transforms, or font metrics in the rendered element or its cloned document. Fix those as separate problems: size the rendering window from the element’s scroll dimensions, verify crop and scroll coordinates, then inspect cloned CSS and fonts.
1. Identify the failure before changing code
Compare the image with the live page at the same state.
- Whole-capture truncation: the bitmap ends partway down or at a fixed edge. This points to canvas dimensions, viewport geometry, crop coordinates, or browser limits.
- Text-only clipping: the surrounding background and boxes are present, but glyphs, descenders, or wrapped lines are cut. Inspect CSS, line boxes, fonts, and the cloned DOM.
- Responsive reflow: text wraps differently or disappears because the rendering window triggers another media query. Treat window dimensions as layout inputs, not merely output settings.
A GitHub report in an html2pdf/html2canvas workflow describes overlapping text and a clipped right margin, but that symptom is an example rather than proof of one universal library defect. Record your browser, html2canvas version, target dimensions, styles, and integration when filing an issue (issue #3013).
2. Prevent a capture from ending early
Match the rendering window to the element
The official FAQ recommends setting windowWidth and windowHeight to the element’s scroll dimensions when output cuts off because of canvas limits (html2canvas FAQ). Measure the target immediately before capture so dynamically loaded content is included.
#1 Best Overall
const target = document.querySelector('#report');
if (!target) throw new Error('Missing #report');
const width = target.scrollWidth;
const height = target.scrollHeight;
html2canvas(target, {
windowWidth: width,
windowHeight: height,
x: 0,
y: 0,
scrollX: 0,
scrollY: 0
}).then(canvas => {
document.body.appendChild(canvas);
});
scrollWidth and scrollHeight include content that overflows the element’s client box. If a child is positioned outside the target or content is still loading, measure again after the final layout state. For a page-level capture, measure the document rather than an inner component:
const width = Math.max(
document.documentElement.scrollWidth,
document.body.scrollWidth
);
const height = Math.max(
document.documentElement.scrollHeight,
document.body.scrollHeight
);
html2canvas(document.documentElement, {
windowWidth: width,
windowHeight: height
});
Check every geometry option
According to the configuration reference:
| Option | What it controls | Typical mistake |
|---|---|---|
width, height |
Final canvas bounds in CSS pixels | Hard-coded values smaller than the target |
x, y |
Crop origin inside the rendered document | Positive offsets removing the first columns or rows |
scrollX, scrollY |
Scroll position used while rendering | Capturing a scrolled state and losing content above it |
windowWidth, windowHeight |
Virtual browser window used for layout and media queries | Responsive breakpoints producing a narrower or shorter layout |
scale |
Multiplier for output pixel dimensions | Creating a canvas too large for browser limits |
Start with no explicit x, y, or crop dimensions unless you need them. Set scroll offsets deliberately. If you want the page at the top, use scrollY: 0; if you want the current viewport, omit it and verify that the current scroll position is intentional.
Test canvas-size limits with scale
Canvas limits vary by browser and device. A very tall page multiplied by a high device-pixel ratio can exceed those limits, causing partial output. scale multiplies pixel dimensions; it does not repair a bad line-height or overflow rule. As a controlled test, lower it:
Rank #2
html2canvas(target, {
windowWidth: target.scrollWidth,
windowHeight: target.scrollHeight,
scale: 1
});
If scale 1 succeeds while a larger scale fails, split the document into sections or accept a lower resolution. Do not claim that scale is a general text-clipping fix; it only changes output resolution and the likelihood of hitting a size limit. The FAQ and renderer implementation explain this distinction (FAQ; canvas renderer source).
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated 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 match3. Fix text that is clipped inside a complete canvas
Inspect overflow and fixed dimensions
Use DevTools on the exact element whose letters are missing. Check computed height, max-height, width, overflow, line-height, white-space, transforms, and ancestor clipping. A fixed-height box with overflow: hidden can cut descenders even when the screenshot dimensions are correct. Temporarily test:
.capture-debug, .capture-debug * {
overflow: visible !important;
max-height: none !important;
}
Apply this only while diagnosing; preserve intentional clipping in production. Remove transforms or fractional sizes temporarily to determine whether a transformed line box is responsible. Also check that a flex or grid child has enough cross-axis space and that a pseudo-element is not covering text.
Verify fonts and metrics
html2canvas positions text using computed font styles and font metrics. A web font that has not loaded, a fallback font with different ascender/descender metrics, or a missing weight can change line boxes. Wait for fonts before capture:
await document.fonts.ready;
const target = document.querySelector('#report');
const canvas = await html2canvas(target, {
windowWidth: target.scrollWidth,
windowHeight: target.scrollHeight
});
Ensure the requested family and weight actually resolve in DevTools. Compare getComputedStyle(element).font between the live page and the capture state. If text is dynamically inserted, wait for its final content and for images that affect wrapping.
Free tools Windows power users keep installed
One-click scans. No signup required.
Use onclone for capture-only corrections
The onclone callback lets you modify the cloned document without changing the visible page (configuration reference). Use it to remove a capture-only constraint or stabilize fonts:
Rank #4
const target = document.querySelector('#report');
const canvas = await html2canvas(target, {
windowWidth: target.scrollWidth,
windowHeight: target.scrollHeight,
onclone: clonedDoc => {
const clonedTarget = clonedDoc.querySelector('#report');
clonedTarget.style.overflow = 'visible';
clonedTarget.style.maxHeight = 'none';
clonedTarget.style.transform = 'none';
}
});
Inspect the clone, not only the live DOM, when a stylesheet, class, or pseudo-element behaves differently during capture. Keep the callback narrowly scoped so it does not alter unrelated components.
4. A repeatable diagnostic procedure
- Capture the smallest affected element and save its
scrollWidth,scrollHeight, computed styles, browser, and html2canvas version. - Set
windowWidthandwindowHeightto those scroll dimensions, withscrollX: 0andscrollY: 0for a top-of-document capture. - Remove explicit crop options. Reintroduce
x,y,width, andheightone at a time. - Await
document.fonts.readyand all content that changes layout. - Test
scale: 1. If that resolves whole-canvas truncation, reduce output size or capture in sections. - If only glyphs remain clipped, use DevTools to inspect overflow, fixed dimensions, line-height, transforms, and font weights.
- Apply a minimal
oncloneoverride and compare the clone’s computed styles with the live element. - Retest at the intended responsive width. A window that is too narrow can trigger a breakpoint and create a different, legitimately clipped layout.
5. Common symptoms, causes, and fixes
| Symptom | Likely cause | Next action |
|---|---|---|
| Image ends at the same height on every run | Canvas/window limit or explicit height | Match window dimensions to scroll dimensions; test scale 1 |
| Left or top content missing | x/y or scroll offsets |
Reset crop and set scroll offsets deliberately |
| Right edge missing only at narrow widths | Responsive media query or insufficient window width | Set the intended windowWidth and inspect breakpoints |
| Letters lose descenders | Fixed line box or hidden overflow | Inspect height, line-height, and ancestor overflow; test in onclone |
| Overlapping lines after font load | Fallback font metrics or missing weight | Await document.fonts.ready and verify computed font |
| Only high-resolution captures fail | Scale multiplied canvas beyond browser limits | Lower scale or split the capture |
6. Reliability and performance considerations
Large canvases consume substantial memory, especially when width, height, and scale are all high. Measure before allocating, avoid capturing hidden off-screen duplicates, and remove debug styles after diagnosis. Capture after layout settles rather than adding arbitrary delays; when a delay is unavoidable, document its reason. For long reports, capture logical sections and assemble them in your PDF workflow instead of requesting one extreme canvas. Keep the exact dimensions and browser in regression tests because media-query changes can alter output without any html2canvas upgrade.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If you need a clean website image rather than a DOM-level html2canvas capture, ScreenshotNeo provides a single HTTP request. Its capture flow accepts consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status.
Recommended Free Tools
cURL (see the ScreenshotNeo API documentation):
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}`);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. Every plan includes its features; the free plan provides 1,000 screenshots per month without a card, and paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Best Value
FAQ
Does increasing scale stop text from being clipped?
No. Scale changes output pixel dimensions and can make canvas-limit failures more likely. It does not correct CSS overflow or font metrics.
Should I always capture the entire document element?
No. Capture the smallest element that contains the required content, then size its rendering window from its scroll dimensions. Whole-document captures are more likely to hit memory and canvas limits.
Why does the screenshot differ from what I see?
The virtual window can trigger different media queries, and the cloned document can have different font-loading or style state. Compare computed styles and the configured window dimensions.
Frequently Asked Questions
Can I solve clipping by adding a delay?
Only if content or fonts are still loading. Prefer awaiting the actual readiness conditions, such as document.fonts.ready and completion of dynamic rendering, instead of relying on an arbitrary delay.
Where are html2canvas canvas limits documented?
The official FAQ at https://html2canvas.github.io/html2canvas/faq/ explains that browser canvas-size limits can cut off output and recommends matching window dimensions to scroll dimensions.
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.

