Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bullet proof solution for page break on table row (<tr>) for printing

It's been days after days we are failing breaking tables as per our need. The solution works for Firefox, but never worked for my favorite browser Chrome in a better way. What we've tried so far is:

We made a class .page-break and made necessary CSS for the different level holders:

@media print{
   /* applied to our table */
   #report-table {
     /*-webkit-region-break-inside: auto; //tried for Chrome */
     page-break-inside:auto
  }

  /* applied to all our <tr> */
  #report-table tbody tr,
  #report-table .behave-tbody .behave-tr{
     /*-webkit-region-break-inside: avoid; //tried for Chrome */
     page-break-inside:avoid;
     break-after: auto;
     page-break-after: auto;
  }

  /* page break specific class */
  .page-break{
     break-after: always;
     /*-webkit-region-break-after: always; //tried for Chrome */
     page-break-after: always;
  }
}

We've learned/found so far

  • Page break works with a block-level element like <h1> <p> etc.
  • Page break works buggy in Google Chrome for Table CSS

Keeping them in mind we proceeded in different ways:

Step #1: Trying the solution with <table> <tr>

    <table id="report-table">
        <thead>
        <tr>
            <th>Head</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>Body Content</td>
        </tr>
        <tr class="page-break">
            <td>Body Content</td>
        </tr>
        <tr>
            <td>Body Content</td>
        </tr>
        </tbody>
    </table>

But that didn't work in Google Chrome. Even though we've learnt that, <tr> itself is a block-level element.

Step #2: Making table absolutely <div> based

<style>
.behave-table{
    display: table;
    width: 100%;
    height: 100%;
    position: relative;
}
.behave-thead{
    display: table-header-group;
}
/* th */
.behave-thead .behave-td{
    background-color: #ededed;
    font-weight: 700;
}
.behave-tbody{
    display: table-row-group;
}
.behave-tr{
    display: table-row;
}
.behave-td{
    display: table-cell;
    padding: 5px;
    vertical-align: top;
}
</style>
<div id="report-table" class="behave-table">
   <div class="behave-thead">
      <div class="behave-tr">
         <div class="behave-td">Head</div>
      </div> <!-- /.behave-tr -->
   </div><!-- /.behave-thead -->
   <div class="behave-tbody">
      <div class="behave-tr">
         <div class="behave-td">Body Content</div>
      </div> <!-- /.behave-tr -->
      <div class="behave-tr page-break">
         <div class="behave-td">Body Content</div>
      </div> <!-- /.behave-tr -->
      <div class="behave-tr">
         <div class="behave-td">Body Content</div>
      </div> <!-- /.behave-tr -->
   </div> <!-- /.behave-tbody -->
</div>

But that didn't work in Google Chrome.

Step #3: Entering Block Level element inside table cell

Being instructed by the SO thread we've tried a block level element inside a blank table cell like below:

<tr><td>Body Content</td></tr>
<tr style="page-break-after: always"><td><h1>Next Section</h1></td></tr>
<tr><td>Body Content</td></tr>

It works partially, for the first page only. We tried hiding the awkward Text block with Bootstrap .sr-only class but with that it din't work at all. We tried replacing the "Next Section" with &nbsp; - it din't work too.

Step #4: Placing a <div> to break using known Block-level elem

<tr><td>Body Content</td></tr>
<div class="page-break"></div>
<tr><td>Body Content</td></tr>

But you know it won't work, because <div> inside a table only work inside a table cell:

What you need to do is make sure the div is inside an actual table cell, a td or th element
- Chris Coyier

Aftermath

We failed our table to break nicely in Google Chrome. :(

Table Row page break isn't working in Google Chrome

like image 903
Mayeenul Islam Avatar asked Jun 28 '16 06:06

Mayeenul Islam


People also ask

How do I insert a page-break in a table in Word?

From the Table Tools, Layout tab, Table group, click the Properties icon. From the Table Properties dialog box, select the Row tab; Select the option 'Allow Row to break across pages'

How do you put a page-break after an HTML element in CSS?

The page-break-after property adds a page-break after a specified element. Tip: The properties: page-break-before, page-break-after and page-break-inside help to define how a document should behave when printed. Note: You cannot use this property on an empty <div> or on absolutely positioned elements.


1 Answers

It is not nice but you could try to go with separat tables for each row. By using the following syntax you can make sure the columns are rendered in the same widths.

<style>
    table {
        page-break-inside: avoid;
    }
</style>

<table>
    <colgroup>
        <col width="25%" />
        <col width="50%" />
        <col width="25%" />
    </colgroup>
    <tr>
        <td>Narrow column</td>
        <td>Wide column</td>
        <td>Narrow column</td>
    </tr>
</table>
<!-- can break -->
<table>
    <colgroup>
        <col width="25%" />
        <col width="50%" />
        <col width="25%" />
    </colgroup>
    <tr>
        <td>Narrow column</td>
        <td>Wide column</td>
        <td>Narrow column</td>
    </tr>
</table>
like image 94
Philipp Wrann Avatar answered Oct 10 '22 18:10

Philipp Wrann