It paginates wrong
Page breaks land in the wrong place
A heading sits alone at the bottom of a page with its section overleaf, a table row splits across the fold, or a signature block orphans onto a page of its own.
What is actually happening
Nothing told the layout where it is allowed to break, so it breaks wherever the content runs out of page. The properties that control this exist and are well supported; they are just not defaults, because a browser laying out a scrolling page has no page boundary to respect.
Confirming it is this and not something that looks like it
Add a temporary outline to the elements you do not want split. If the outline crosses the page boundary, the break rule is missing rather than being overridden.
The fix
Declare the units that must stay whole with break-inside: avoid, and keep headings with what follows using break-after: avoid. Both take effect during pagination and cost nothing when the content happens to fit.
/* Things that must not split down the middle. */
.line-item,
.totals,
.signature-block,
figure,
tr {
break-inside: avoid;
}
/* A heading that ends up last on a page moves down with its section. */
h2,
h3 {
break-after: avoid;
}
/* A section that should always start fresh. */
.appendix {
break-before: page;
}
/* Minimum lines either side of a break, for body copy. */
p {
orphans: 3;
widows: 3;
}If that was not it
These produce the same symptom often enough to be worth ruling out before assuming the fix above did not work.
- The older page-break-inside property, which some codebases still carry and which is now an alias
- break-inside: avoid on an element taller than one page, which cannot be honoured and is silently ignored
- A wrapping element with overflow: hidden, which makes its children invisible to pagination
- Flex and grid containers, where break rules apply to items rather than to the container
Frequently asked
Does this happen with every rendering engine?
The behaviour behind it is not specific to one tool. Nothing told the layout where it is allowed to break, so it breaks wherever the content runs out of page. Anything rendering HTML to a paged medium has to make the same decision, so the fix travels with you if you change how the render happens.
Will this show up as an error in my logs?
No, and that is what makes it expensive. A document that renders wrong is still a successful render as far as every log line is concerned. It is found by someone opening the file, which is usually the customer.
Related failures
Problems people arrive at from the same starting point, or mistake for this one.
Table headers do not repeat on the next page
Header repetition is driven by table sectioning, not by styling.
There is an extra blank page at the end
Something extends a fraction of a millimetre past the end of the last page.
Content is cut off at the right edge of the page
The element is wider than the page's content box and has nothing telling it to wrap.
Page numbers are missing or all show 1
Page numbers come from the footer template's special classes, not from CSS counters in the document body.
The PDF comes out the wrong paper size
Two things can set the page size and they disagree.
CSS for paged documents, and what actually works
Which parts of the paged media specification a browser-based render implements.
Everything that goes wrong, by category
The full list, grouped by where in the pipeline it breaks.
Paste your markup and see the rendered document, without signing up.