Free tools Windows power users keep installed
One-click scans. No signup required.
Start with a row-level pagination test, not a global rewrite. Add the legacy avoidance rules below to the rows that are leaving gaps, then render the same document with the exact wkhtmltopdf binary used in production:
tr {
page-break-inside: avoid;
page-break-before: avoid;
page-break-after: avoid;
}
This solved the reported whitespace in wkhtmltopdf issue #4868, but it is not a universal fix. Other reports show ignored rules, split rows, repeated headers separated from data, and long borders at page bottoms. Treat the CSS as a controlled experiment and verify it with your own HTML, operating system, Qt build, fonts, margins and header/footer settings.
Why wkhtmltopdf leaves blank areas around table rows
wkhtmltopdf paginates HTML through a QtWebKit-based renderer. When a row cannot fit in the remaining space, the renderer may move it to the next page instead of splitting it. The unused area then looks like unexplained white space. A repeated table header can make the effect more confusing: the header may be printed first, while the row it belongs to is moved away or leaves a visible gap.
The pagination code is known to be limited and inconsistent. Issue #2141 describes page-break-inside: avoid as a table-level workaround that fails in some scenarios, while issue #4868 records one successful result after all three avoidance declarations were applied to tr. A report against wkhtmltopdf 0.12.2.4 with patched Qt on Windows kept rows together but produced long cell borders at the bottom of a page and repeated a header before the displaced row. Another report against 0.12.4 describes spaces between repeated headers and rows even when rules were added to table, tr, thead and tfoot.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errors#1 Best Overall
Apply the smallest practical fix
- Record the renderer first. Save the complete output of
wkhtmltopdf --version, the operating system, how wkhtmltopdf was installed, and whether the build uses patched Qt. Different distributions and builds can paginate the same markup differently. - Make a minimal reproduction. Keep the same table structure, CSS, fonts, paper size, margins, headers and footers as the failing document. Remove unrelated page content, but do not silently change anything that can affect line wrapping.
- Apply the three declarations to rows. Begin with the affected table or a class of rows rather than every row in every table.
- Render twice. Compare the original and modified PDFs page by page. Check the bottom of the preceding page, the top of the next page, repeated headers, borders and text flow.
- Revert if the artifact changes shape. If rows stay together but borders become abnormally long or a header appears without useful data, narrow the selector or remove the rule.
Minimal test document
This deliberately small file lets you isolate pagination from application templates. Replace the sample rows with the smallest structure that still reproduces your gap.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
@media print {
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #777; padding: 6px; vertical-align: top; }
thead { display: table-header-group; }
tr {
page-break-inside: avoid;
page-break-before: avoid;
page-break-after: avoid;
}
}
</style>
</head>
<body>
<table>
<thead><tr><th>Item</th><th>Description</th></tr></thead>
<tbody>
<tr><td>A</td><td>A short row</td></tr>
<tr><td>B</td><td>The row that normally moves across the page boundary</td></tr>
</tbody>
</table>
</body>
</html>
Render it with the same invocation your application uses, for example wkhtmltopdf test.html test.pdf. The command itself is less important than keeping the binary, input, fonts and page settings identical between runs.
Scope the rule instead of forcing every row to stay intact
Avoidance has a cost: if a row is taller than the remaining page area, the renderer must move the entire row, creating a larger gap. If a row is taller than a page, avoiding a split may be impossible or may produce severe layout artifacts. Start with a class on rows that represent one logical record:
tr.keep-together {
page-break-inside: avoid;
page-break-before: avoid;
page-break-after: avoid;
}
Use the class only where splitting would make the document hard to read, such as an invoice line with a multi-line explanation. Leave ordinary, short rows available for normal flow if applying the rule globally creates excessive white space.
Test each table type separately. A compact data table, a table containing images, and a table with long paragraphs exercise different layout paths. Do not assume that a rule that helps one table should be copied to every table in the document.
Rank #2
Capture the configuration that controls the result
Before comparing a successful and unsuccessful render, record these dimensions in your bug report or build log:
| Dimension | What to record | Why it matters |
|---|---|---|
| wkhtmltopdf | Complete --version output and package or binary distribution |
Pagination behavior differs among releases and builds. |
| Qt | Whether the binary uses patched Qt | The Debian buster manpage describes page-break-inside as only a partial remedy when patched Qt is used. |
| Operating system | OS and architecture | Issue reports describe different outcomes across environments. |
| Markup and CSS | Table nesting, row content, widths, fonts and print rules | Small wrapping changes can move a row to another page. |
| Page furniture | Paper size, margins, headers and footers | These reduce usable page height and can expose a break edge. |
Pin these inputs when you need reproducible PDFs. A change in installed fonts or a package rebuild can alter line wrapping without any application-code change.
Understand the common failure patterns
The CSS is ignored
Some wkhtmltopdf builds do not honor the avoidance declaration consistently. Confirm that the rule reaches the actual tr element, then test the minimal file with the production binary. If the minimal file fails too, the limitation is likely in the renderer or build rather than your template.
Outdated 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 matchWindows 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 reinstallThe row stays together but the gap grows
This is the expected trade-off when a row no longer fits in the remaining page area. Apply the class only to rows that need atomic treatment, shorten unusually long cell content, or accept a natural split where readability allows it. Do not hide the gap by changing margins until you have checked whether a row was deliberately moved.
Long borders appear at the page bottom
The 0.12.2.4 Windows report described long cell borders after page-break-inside: avoid kept rows together. Compare border rendering as well as text position. If the artifact is unacceptable, remove the rule from that table or reduce its scope; a visually intact row is not a successful fix if its borders are misleading.
A repeated header appears without the row you expected
Inspect the page containing the header and the following page. A header can be repeated before the renderer decides that the next row must move. Rules on thead and tfoot do not guarantee that header-row relationship. Test the table with and without row avoidance and keep the version whose page semantics are clearer.
There is a gap between a repeated header and the first data row
Issue #4868’s success should not be generalized to this case: issue #2141 and the 0.12.4 report document scenarios where avoidance rules fail or introduce spacing. Reduce the input to one table, one header and enough rows to cross a page boundary. That tells you whether the gap is caused by the table itself or by surrounding content and page furniture.
The result changes after an upgrade or deployment
Compare the saved version output, OS, Qt patch status and installed fonts. Re-run the minimal reproduction before changing CSS. If only the binary changed, treat the result as a renderer-compatibility change and keep the old and new PDFs for review.
A disciplined troubleshooting sequence
- Freeze inputs: copy the exact HTML, CSS, assets and fonts used for the failing PDF.
- Check the boundary: identify the last row on the previous page, the first row on the next page and whether a header was repeated.
- Test row avoidance: add all three declarations to
tr, not just one, and render with the production binary. - Inspect side effects: look for blank header pages, long borders, clipped content and larger gaps.
- Narrow the selector: apply the declarations only to the affected table or rows if global rules are disruptive.
- Remove the workaround when it loses: keeping a rule that merely moves the defect is not progress.
- Package a reproducible report: include the smallest HTML file, CSS, command, version output, OS, Qt status and before/after PDFs.
When CSS is not enough
The Debian buster wkhtmltopdf manpage characterizes patched-Qt support for page-break-inside as something that remedies pagination “somewhat,” and says there is no easy solution to the underlying problem. That qualification matches the issue history: one reporter fixed extra white space, while other reports show failures and cosmetic regressions.
The upstream wkhtmltopdf repository was archived and made read-only by its owner on January 2, 2023. Do not plan around an upstream correction arriving for these historical pagination issues. If clean table pagination is a hard requirement, evaluate a different rendering engine against your own documents, fonts, headers, footers and legal layout requirements. The available issue evidence does not establish a universally best replacement, so make that decision with a representative document set rather than a synthetic benchmark.
Rank #4
- Funny saying for any front-end developer, web developer, computer programmer, computer systems engineer, mobile app developer, software developer, or code lover who likes to code, make funny programming jokes, and take memorable photos.
- Wear it proudly at International Programmers' Day, school, coding classes, or coding communities! It also makes a funny present for a computer programming lover friend.
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
Performance, reliability and operating cost
The CSS test itself has no licensing or service cost, but every extra render in a diagnostic loop consumes build or server time. Keep a small fixture for fast comparisons and reserve full production documents for final verification. Reliability comes from pinning the wkhtmltopdf binary, Qt build, OS image and fonts, then reviewing PDFs when any of those inputs changes. There is no controlled benchmark in the available issue reports, so avoid promising a particular speed or page-count improvement from these declarations.
Recommended Free Tools
Or skip the browser setup
If your real requirement is a clean screenshot or PDF of a web page rather than wkhtmltopdf-specific table pagination, ScreenshotNeo provides a single HTTP request. It is not a patch for wkhtmltopdf and it does not preserve wkhtmltopdf’s exact rendering behavior; it is an alternative capture path when browser automation is the part you want to remove.
Before capture, ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed; the response identifies the page and billing result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.
Use the API documentation at https://screenshotneo.com/docs/ for authentication and options. The following calls are complete starting points:
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(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
Every plan includes the available capture controls, including full-page screenshots with lazy images loaded, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF paper size and page ranges, custom CSS and JavaScript, clicks, selector or network-idle waits, request and resource blocking, headers, cookies, user agent, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting and an OpenAPI specification. Parameter names used by other screenshot APIs are accepted to ease migration.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →| Plan | Included shots | Price |
|---|---|---|
| Free | 1,000 per month | $0; no card |
| Starter | 3,000 | $5 |
| Growth | 15,000 | $15 |
| Pro | 60,000 | $39 |
| Scale | 250,000 | $99 |
| Business | 1,000,000 | $249 |
Yearly billing gives two months free. Start with 1,000 free screenshots a month with no card if this capture workflow fits your use case.
Best Value
- Programming Language Lover Code Apparel. App or Web Design and Development Expert Funny Dress. Best Valentines Idea For Coding Lover. HTML Code or Meaning Costume
- Funny I Know HTML - How To Meet Ladies Computer Programmer Quotes
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
FAQ
Should I add only page-break-inside: avoid?
For the reported whitespace case, the successful issue #4868 report used the inside, before and after declarations together on tr. Test that combination first, then narrow or remove it if your renderer produces artifacts.
Does this guarantee that a row will never split?
No. wkhtmltopdf’s pagination behavior is documented through inconsistent issue reports, and the Debian manpage calls the remedy partial. A row can still move, leave a gap or interact badly with repeated headers.
Is the archived repository still relevant to current deployments?
It is relevant as historical evidence for known behavior, but its read-only status means you should validate any workaround against the exact binary and build you deploy rather than wait for an upstream fix.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Frequently Asked Questions
Can I rely on this CSS across operating systems?
No. Issue reports show outcomes vary by wkhtmltopdf version, operating system and patched-Qt build; reproduce with the production binary.
What should a useful bug report contain?
Include the smallest HTML/CSS reproduction, complete wkhtmltopdf –version output, OS, package or binary source, Qt patch status, fonts, page settings and before/after PDFs.
When should I stop tuning CSS?
Stop when row avoidance still causes unacceptable gaps, borders or header placement. At that point compare another renderer using representative production documents.
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.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.




