HTML table split across PDF pages

Long tables are where print-to-PDF falls apart. A row gets sliced through the middle at the page edge, page two starts with numbers and no column names, and the last three columns are simply gone.

Each of those has a different cause. All of them are fixable in a handful of lines of print CSS.

Rows cut in half at the page break

Cause: by default the browser breaks wherever the page ends, even mid-row.

Fix:

@media print {
  tr,
  img,
  figure,
  .card {
    break-inside: avoid;
    page-break-inside: avoid; /* older engines */
  }
}

Rows that would straddle the break move to the next page. The limit: a single row taller than a page — a cell with a long stack trace, say — will always split. Truncate or wrap those cells for print.

Headers missing after page one

Cause: the header row isn't in a <thead>.

Browsers repeat <thead> at the top of every printed page when a table breaks. Many generated reports put the header in the first <tr> of <tbody>, or fake it with divs, so it prints once.

<table>
  <thead>
    <tr>
      <th>Test</th>
      <th>Status</th>
      <th>Duration</th>
    </tr>
  </thead>
  <tbody>
    …
  </tbody>
</table>

A <tfoot> repeats the same way at the bottom, which is handy for running totals.

Right-hand columns cut off

Cause: the table is wider than the printable area. On screen it scrolled sideways; paper doesn't scroll.

Fixes, roughly in order of how much they change the report:

@page {
  size: A4 landscape; /* or: letter landscape */
  margin: 10mm;
}

@media print {
  table {
    width: 100%;
    table-layout: fixed;
    font-size: 9pt;
  }
  td,
  th {
    overflow-wrap: anywhere; /* lets long IDs and URLs wrap */
  }
  .screen-only {
    display: none;
  }
}

Landscape alone usually rescues an eight-to-ten-column table. Beyond that, decide which columns belong on paper and hide the rest with a class.

Only the first screenful of rows prints

Cause: the table sits in a scroll container — max-height: 600px; overflow: auto — and print shows exactly what that box shows.

@media print {
  .table-wrapper {
    max-height: none;
    height: auto;
    overflow: visible;
  }
}

Same story for tabs and collapsed <details>: print captures the current state. And if the table lives inside a display: flex or display: grid parent, set that parent to display: block in print; some engines won't break flex and grid children across pages cleanly.

The sticky header that prints over every page

A position: sticky or position: fixed header or toolbar can repeat on every page and sit on top of the first rows. Hide app chrome in print:

@media print {
  header,
  nav,
  .toolbar {
    display: none;
  }
}

Do all of it without touching the file

The free HTML to PDF tool takes pasted HTML and injects the parts above for you: page size and orientation, margins, break-inside: avoid on rows and figures, background colors kept, and a field for CSS selectors to hide. Preview, then save from the print dialog. It runs entirely in your browser.

Colors vanishing too? That's a separate default — see background colors missing when printing.

Or send the table, not a picture of it

The reason long tables print badly is that they were never meant for paper: they scroll, sort and filter. A PDF freezes them at whatever page size the reader's printer picked.

If the PDF is just the delivery mechanism, publish the report to Comma and send the link instead. The table keeps its scroll and its sorting, the link always shows the latest run, and reviewers comment on the exact row instead of circling it on page 7.

Try it

Publish a report →

Related