Page break is not working with the tbody issue

19,424

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.

.

Share:
19,424
Suresh Karia
Author by

Suresh Karia

All that is gold does not glitter, Not all those who wander are lost;

Updated on June 14, 2022

Comments

  • Suresh Karia
    Suresh Karia almost 2 years

    I am generating a print report using table in layout. The page has multiple tbody inside a table; While Printing the page it requires a page-break-after each tbody

    To do so, I have applied

    @media print {
        tbody{
            page-break-after: auto;
            page-break-inside: avoid;
            border: none !important;
            margin-bottom: 20px !important;
        }
    }
    

    What is the issue?

    • while applying the style page-break-after to a tbody , page-break is not working see here

    • but when applying display:block to tbody, it gives desired result but the layout of table is being distorted after changing tbody display:table-row-group to display:block See Here

    I want to break the page after tbody using page-break-after: auto;.

    Scenario is given below

    table

    • Jukka K. Korpela
      Jukka K. Korpela over 9 years
      It is unclear what you want. First you say you want page break after each tbody, then you say you don’t. And if you set display: 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).
    • Suresh Karia
      Suresh Karia over 9 years
      I want page break while tbody display:table-row-group
    • Jukka K. Korpela
      Jukka K. Korpela over 9 years
      Still not clear at all. Your code shows not attempt at forcing page breaks after tbody elements, only preventing page breaks inside them. Do you want that, or do you want a page break after each tbody? If the latter, what happens on which browser(s) when you try the obvious page-break-after: always?
  • Suresh Karia
    Suresh Karia over 9 years
    Thank you it is helpfull
  • Muneem Habib
    Muneem Habib almost 9 years
    How to apply page-break inside table body. Like table has huge amount of data and it needs 5 pages to be printed then how to apply pagebreak inside tbody?
  • Vedmant
    Vedmant almost 6 years
    It doesn't work, example jsfiddle.net/abhitalks/DTcHh/3054 still breaks page on the middle of second tbody screencast.com/t/M5pzpMEIJq0j