Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Use forced breaks for boundaries and avoidance rules for content that should stay together. In paged HTML-to-PDF workflows, break-before: page starts a table or section on a new page, while break-inside: avoid asks the formatter not to split a table, row, or row group when it can fit. These are requests to the layout engine, not guarantees: a table taller than the available page area must be split, and support varies by PDF renderer.

Choose between forcing a break and avoiding one

Decide what outcome you need before writing CSS. A forced break creates a page boundary at a specific location. An avoidance rule merely discourages an internal break. The Prince User Guide states that break-inside cannot create a forced break; use break-before or break-after for that purpose (Prince User Guide 12).

Goal Property Effect
Start a table or section on a new page break-before: page Forces a page break before the selected element.
End a section and begin the next content on a new page break-after: page Forces a page break after the selected element.
Keep a compact table together if it fits break-inside: avoid Discourages an internal break.
Discourage splitting rows tr { break-inside: avoid; } Asks the formatter to keep each row intact.

The older page-break-before, page-break-after, and page-break-inside properties remain useful for compatibility with older engines. The CSS 2.2 page-break specification documents the legacy names (W3C CSS 2.2).

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

CSS patterns that work for common table layouts

Start a table on a new page

/* The table begins at the top of a fresh page */
.new-page-table {
  break-before: page;
  page-break-before: always; /* legacy fallback */
}

Apply the class to the table itself or to a wrapper that is in normal document flow. A forced value such as page takes precedence over an avoidance value at the same potential break location, according to the W3C paged-media rules.

Keep a short table together

.compact-table {
  break-inside: avoid;
  page-break-inside: avoid; /* legacy fallback */
}

This is appropriate for a table that is shorter than the printable page area. It does not shrink the table or override margins, headers, footers, or other content that consumes that area.

Keep rows from breaking

tr {
  break-inside: avoid;
  page-break-inside: avoid;
}

Targeting rows is safer than insisting that a long table remain one piece. In Prince, pagination rules can apply to in-flow block elements, table rows, and row groups. Floated and absolutely positioned content falls outside the documented conditions (Prince pagination guidance).

Keep a header and group together

thead,
tbody,
.table-group {
  break-inside: avoid;
}

Use row groups when a logical subsection should remain together, but keep expectations realistic: the formatter may still move or split content when the group is larger than the remaining page space.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What happens when a table is taller than a page?

No keep-together rule can make content taller than a page fit on one page. A table or row group that exceeds the available page height must split, overflow, or be reflowed according to the renderer. Prince explicitly documents this limitation (Prince paged-media documentation).

  • Use break-inside: avoid on individual rows so each row remains readable where possible.
  • Allow the table body to continue across pages rather than applying avoidance to the entire oversized table.
  • Repeat column headings with a table header group when your formatter supports it, for example <thead>.
  • Reduce excessive cell padding, font size, or margins only when that improves readability; do not hide rows to force a visual result.

Target the smallest useful element

Pagination is more predictable when the rule is attached to the thing that should stay together. For a small table, target the table. For an indivisible row, target the row. For a chapter-like boundary, target the heading or section wrapper with break-before: page. Applying avoidance to a large wrapper can cause an unexpectedly large blank area because the formatter tries to move the whole wrapper to the next page.

Keep the content in normal flow. Prince’s documented behavior does not promise the same avoidance behavior for floated or absolutely positioned elements. If a table is positioned, remove the positioning for the print stylesheet or create a normal-flow print variant.

Legacy properties and renderer support

Modern properties are the clearest expression of intent, but production documents often pass through several engines. You can include both forms:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
.report-section {
  break-before: page;
  page-break-before: always;
}

.report-table {
  break-inside: avoid;
  page-break-inside: avoid;
}

Do not assume that a browser preview, a server-side converter, and Prince produce identical pagination. The W3C CSS Print Profile provides implementation guidance, while individual formatters define their supported behavior (CSS Print Profile). Generate a PDF with the exact production engine and version, then inspect pages containing short, borderline, and oversized tables.

A practical implementation procedure

  1. Define the boundary. Decide whether the table must start on a new page, end before a new section, or simply avoid row splits.
  2. Mark the HTML. Use semantic <table>, <thead>, <tbody>, and classes such as new-page-table.
  3. Add modern and legacy rules. Pair break-* declarations with the corresponding page-break-* fallback when older converters are possible.
  4. Apply avoidance narrowly. Start with the table or row, not a page-sized parent container.
  5. Render with production settings. Use the same paper size, margins, fonts, headers, footers, and formatter version used by your application.
  6. Inspect edge cases. Test a table that fits, one that nearly fills a page, one that is taller than a page, and one preceded by a heading near the bottom margin.
  7. Adjust the source. If the output is poor, change the rule or document structure; do not expect CSS to violate physical page limits.

Troubleshooting table pagination

The table still splits despite break-inside: avoid

Check whether the table or row is taller than the available page area. If it is, splitting is unavoidable. Also verify that the rule reaches the element, that the content is in normal flow, and that the selected renderer supports avoidance for tables or rows. Try applying the rule to the row rather than the entire table.

The table starts on a new page unexpectedly

Search ancestor elements and print stylesheets for break-before, page-break-before, or a forced break after the previous section. A forced break takes precedence over an avoidance request at a potential break point.

A large blank area appears before the table

The formatter may be honoring break-inside: avoid on a wrapper that cannot fit in the remaining space. Move the rule to the table or rows, remove it from the large wrapper, and check whether floats or positioned elements are involved.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Browser preview and PDF output differ

They are different layout engines. Compare output from the actual PDF formatter, not only a browser’s print preview. Record the formatter and version in your build so a change can be reproduced.

Rows overlap, disappear, or have inconsistent breaks

Validate the HTML table structure, remove absolute positioning from print content, and test with simple in-flow markup. Then add styles back incrementally. Malformed row groups and unsupported layout features can defeat pagination rules.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability, and maintenance

Pagination rules rarely dominate rendering time; complex tables, large images, web fonts, and scripts usually do. Reliability improves when documents use deterministic fonts, fixed print dimensions, semantic tables, and a pinned formatter version. Keep a small regression PDF set in continuous integration and compare page boundaries after CSS or formatter upgrades.

Do not encode business meaning solely in a page break. A page is a presentation boundary that can move when text, fonts, localization, or paper size changes. Keep headings with their content semantically, then use forced breaks only for intentional chapter or appendix boundaries.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your goal is to obtain a clean reference image or PDF of a rendered page while debugging a report, ScreenshotNeo provides a URL-based screenshot API. It accepts 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 response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

One-call cURL example (see the ScreenshotNeo 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 includes full-page capture, element selection, custom CSS and JavaScript, waits, request blocking, headers and cookies, device presets, PDF options, caching, signed links, asynchronous jobs, bulk capture, and an API usage endpoint. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Frequently Asked Questions

Can CSS guarantee that a table never splits across PDF pages?

No. Avoidance rules are honored only where the formatter can satisfy them; content taller than the available page must be split or reflowed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I use break-before or break-inside to start a table on a new page?

Use break-before: page. break-inside: avoid only discourages internal splits and cannot force a new page.

Why test with the production PDF engine?

Pagination support and edge-case behavior differ among browsers, converters, and formatter versions, so a preview is not proof of production output.

The Bottom Line

Use break-before: page for intentional boundaries and narrowly scoped break-inside: avoid for tables or rows that can fit. Keep oversized tables in normal flow, retain legacy fallbacks where needed, and verify the generated PDF with your production formatter.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.