How to Handle Page Breaks when Printing a Large HTML Table
Solution with the CSS break-inside property
Read our snippet if you need to print an HTML table with many rows over multiple pages.
Example of handling page breaks when printing a large table:
<!DOCTYPE html>
<html>
<head>
<style>
@media print {
table {
page-break-inside: avoid;
}
thead {
display: table-header-group;
}
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1, Column 1</td>
<td>Row 1, Column 2</td>
<td>Row 1, Column 3</td>
</tr>
<!-- more rows... -->
</tbody>
</table>
</body>
</html>
The @media print
rule specifies print-specific styles that will be applied when the <table> is printed. Within this rule, we set page-break-inside: avoid;
on the table
element to prevent the table from being split across pages. This property tells the browser to try to keep the entire table on one page, rather than breaking it up. Note that this property is not supported in all browsers, so you may need to experiment with other approaches if you encounter issues.
We also set display: table-header-group;
on the thead
element. This ensures that the table header (the tr
containing the column headings) is repeated on each page, which makes it easier to understand the content on each page of the printed table.
The rest of the HTML is a basic table with a header row (thead
) and a body (tbody
) containing multiple rows (tr
) of data. Note that this example doesn't include any specific page breaks within the table, as it assumes the table will fit on a single page.
Avoiding footer on every page break
To prevent a table footer from being displayed on every page break within the table body, you can add the following CSS rule:
tfoot {
display: table-footer-group;
}
This will ensure that the table footer is only displayed at the end of the table, rather than on every page break within the table body.
Here's an example:
<!DOCTYPE html>
<html>
<head>
<style>
tfoot {
display: table-footer-group;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1, Column 1</td>
<td>Row 1, Column 2</td>
<td>Row 1, Column 3</td>
</tr>
<tr>
<td>Row 2, Column 1</td>
<td>Row 2, Column 2</td>
<td>Row 2, Column 3</td>
</tr>
<tr>
<td>Row 3, Column 1</td>
<td>Row 3, Column 2</td>
<td>Row 3, Column 3</td>
</tr>
<!-- and so on... -->
</tbody>
<tfoot>
<tr>
<td>Footer 1</td>
<td>Footer 2</td>
<td>Footer 3</td>
</tr>
</tfoot>
</table>
</body>
</html>
Breaking after a specific row
To break after a specific row, you can use the nth-child
selector in combination with the page-break-after
property. For example, to break after every 5th row, you can use the following CSS:
tr:nth-child(5n) {
page-break-after: always;
}
This will force a page break after every 5th row.
Here's an example of how to break a large HTML table into pages after a specific number of rows, in this case 5 rows per page:
<!DOCTYPE html>
<html>
<head>
<style>
@media print {
table {
page-break-inside: avoid;
}
tr {
break-inside: avoid;
}
tbody {
display: block;
}
tbody tr:nth-child(5n + 1) {
page-break-before: always;
}
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1, Column 1</td>
<td>Row 1, Column 2</td>
<td>Row 1, Column 3</td>
</tr>
<tr>
<td>Row 2, Column 1</td>
<td>Row 2, Column 2</td>
<td>Row 2, Column 3</td>
</tr>
<tr>
<td>Row 3, Column 1</td>
<td>Row 3, Column 2</td>
<td>Row 3, Column 3</td>
</tr>
<tr>
<td>Row 4, Column 1</td>
<td>Row 4, Column 2</td>
<td>Row 4, Column 3</td>
</tr>
<tr>
<td>Row 5, Column 1</td>
<td>Row 5, Column 2</td>
<td>Row 5, Column 3</td>
</tr>
<tr>
<td>Row 6, Column 1</td>
<td>Row 6, Column 2</td>
<td>Row 6, Column 3</td>
</tr>
<tr>
<td>Row 7, Column 1</td>
<td>Row 7, Column 2</td>
<td>Row 7, Column 3</td>
</tr>
<!-- and so on... -->
</tbody>
</table>
</body>
</html>
In this example, we're using the @media print
rule to apply print-specific styles to the table. We're setting page-break-inside: avoid;
on the table to ensure that table rows aren't split across pages, and break-inside: avoid;
on the table rows to prevent them from being split. We're also setting display: block;
on the table body to ensure that it takes up the full width of the page.
Finally, we're using the nth-child
selector to select every 5th row in the table body and applying page-break-before: always;
to force a page break before that row. This results in 5 rows per page.