Page break is not working with the tbody issue
Asked Answered
P

4

15

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

Plutonian answered 3/1, 2015 at 9:5 Comment(3)
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).Dort
I want page break while tbody display:table-row-groupPlutonian
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?Dort
W
20

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.

.

Widescreen answered 3/1, 2015 at 12:35 Comment(2)
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?Tycoon
It doesn't work, example jsfiddle.net/abhitalks/DTcHh/3054 still breaks page on the middle of second tbody screencast.com/t/M5pzpMEIJq0jAdvocacy
L
0

I managed this problem by closing and opening a new table instead of grouping rows in <tbody>. In table css you can put:

display: block;

and page-break works there without breaking layout of the table.

Lysenkoism answered 10/7, 2020 at 8:46 Comment(0)
L
0

I solved it wrapping the table

<div style="display: block; break-inside: avoid">
   <table>
      <tr>
         <td>
            Col 1
         </td>
         <td>
            Col 2
         </td>
      </tr>
   </table>
   <p style="page-break-after: always;"> </p>
</div>
Lanna answered 10/10, 2021 at 14:40 Comment(0)
A
-1

This is possible by doing this:

tbody {
    display: block;
    width: 100%;
    page-break-after: always;
    page-break-inside: avoid;
    page-break-before: avoid;
}
Alpinist answered 24/4, 2018 at 16:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.