This is a known problem. page-break
properties apply only to block-level elements.
This is why you are not getting page-breaks on your tbody
. When you explicitly change tbody
from its display: table-row-group
to display: block
, then the page-breaks will start applying. But, then this will break the layout of your table.
As per specs: http://www.w3.org/TR/CSS21/page.html#page-break-props
User Agents must apply these properties to block-level elements in the
normal flow of the root element. User agents may also apply these
properties to other elements, e.g., 'table-row' elements
Although, the specs say that user agents may also apply these properties on table-row
, the word "may" plays its role and the behaviour is not uniform across implementations.
Solution:
Apply page-break to a block-level pseudo-element on your tbody
instead of directly applying it to tbody
.
Like this:
tbody::after {
content: ''; display: block;
page-break-after: always;
page-break-inside: avoid;
page-break-before: avoid;
}
Here is your working fiddle: http://jsfiddle.net/abhitalks/DTcHh/3054/
Also, note that this alone will not solve all of your problems. You must carefully define your page-context and appropriate margins and dimensions to suit your use-case.
This will give you a start:
@page {
size: A4;
margin: 0;
}
@media print {
html, body {
width: 210mm;
height: 297mm;
}
...
}
Here is a snippet with a very simple example to try it out. To test, check the print preview, there should be two page-breaks, one after each tbody
.
Snippet:
table, th, td { border: 1px solid gray; border-collapse: collapse; }
th, td { padding: 8px; }
tbody:first-of-type { background-color: #eee; }
@page {
size: A4;
margin: 0;
}
@media print {
html, body {
width: 210mm;
height: 297mm;
}
tbody::after {
content: ''; display: block;
page-break-after: always;
page-break-inside: avoid;
page-break-before: avoid;
}
}
<div>
<a href="#" onClick="window.print();">Print</a>
</div>
<hr />
<table>
<thead>
<tr>
<th>Head 1</th>
<th>Head 2</th>
<th>Head 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1 Cell 1</td>
<td>Row 1 Cell 2</td>
<td>Row 1 Cell 3</td>
</tr>
<tr>
<td>Row 2 Cell 1</td>
<td>Row 2 Cell 2</td>
<td>Row 2 Cell 3</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Row 3 Cell 1</td>
<td>Row 3 Cell 2</td>
<td>Row 3 Cell 3</td>
</tr>
<tr>
<td>Row 4 Cell 1</td>
<td>Row 4 Cell 2</td>
<td>Row 4 Cell 3</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Foot 1</th>
<th>Foot 2</th>
<th>Foot 3</th>
</tr>
</tfoot>
</table>
Disclaimer: I have tested it only against Chrome v39. You need to apply your own tests.
.
tbody
, then you say you don’t. And if you setdisplay: block
, you are breaking table layout. Please focus on describing exactly what you want and how your best attempt (here apparently the first one) fails in doing that, and on which browser(s). – Dorttbody
elements, only preventing page breaks inside them. Do you want that, or do you want a page break after eachtbody
? If the latter, what happens on which browser(s) when you try the obviouspage-break-after: always
? – Dort