CSS page breaks for PDF: control where pages start and end

The modern break properties, when to use each, and patterns for tables, headings and cards.

Updated · 5 min read

When HTML becomes a PDF, the browser has to decide where each page ends. Left alone, it will happily split a table row, strand a heading at the bottom of a page or cut a card in half. CSS gives you three properties to guide those decisions.

The three properties

PropertyUse it toTypical value
break-beforeStart an element on a new pagepage
break-afterForce a new page after an element, or avoid onepage or avoid
break-insideKeep an element on one page if it fitsavoid

The older page-break-before, page-break-after and page-break-inside properties still work in Chromium as aliases, so existing templates don’t need rewriting. Use the modern names for new work.

Start sections on a new page

.chapter { break-before: page; }
.chapter:first-of-type { break-before: auto; } /* no blank first page */

In our tests the converter ignores a forced break before the very first element, so page one is never left empty; the second rule is a harmless safeguard for other print tools.

Keep headings with what follows

h1, h2, h3 { break-after: avoid; }

avoid is a request, not a guarantee. If keeping things together is impossible, the browser breaks anyway rather than losing content.

Stop cards, figures and rows splitting

figure, .card, blockquote, tr { break-inside: avoid; }

This works well for elements shorter than a page. An element taller than a page must split; there is nowhere else for it to go.

Long tables

Chromium repeats a table’s <thead> at the top of every printed page the table spans, so readers never lose the column names. Put header cells in <thead> rather than the first body row:

<table>
  <thead><tr><th>Date</th><th>Item</th><th>Amount</th></tr></thead>
  <tbody>
    <tr><td>1 Oct</td><td>Design work</td><td>£400.00</td></tr>
    …
  </tbody>
</table>

<style>
  tr { break-inside: avoid; }
</style>

Orphans and widows

For paragraphs, orphans and widows set the minimum number of lines left at the bottom or carried to the top of a page. The default is 2; raising it to 3 gives text a more typeset look:

p { orphans: 3; widows: 3; }

Why a break might be ignored

  • Flex and grid containers. Breaks between items inside some flex or grid layouts are handled less predictably than in normal block flow. If a break isn’t honoured, try a block layout inside @media print.
  • Absolutely positioned or floated elements. These sit outside normal flow, so break rules don’t apply to them in the usual way.
  • Fixed heights and overflow: hidden. A container clipped to a height can hide content that would have flowed onto the next page.

Next: the print CSS checklist covers margins, backgrounds and hiding screen-only elements.