Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Selector for first-child after a page break

Tags:

css

How can I style the first-child AFTER a page break has occurred?

The ultimate situation I'm facing is that I would like to style the first row of a table differently, and when printing the table spans multiple pages. I successfully used :first-child to style the first row. I also successfully avoided page breaks inside rows. I can not figure out how to style the first row on the second page of the table, though.

I'm familiar with the css pseudo class first-child (http://www.w3schools.com/cssref/sel_firstchild.asp), and I'm also familiar with the css print property page-break-inside (http://www.w3schools.com/cssref/pr_print_pagebi.asp). I'm unable to get them to play nicely together?

EDIT: Adding code sample

HTML:
<table>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
</table>

CSS:
table tr:first-child td { border-top: solid red 2px; }
table tr { page-break-inside: avoid }
like image 644
user2115916 Avatar asked Oct 21 '14 18:10

user2115916


2 Answers

Okey, direct answer — you can not do that as how you want.

Edit: oh, looks like I answer for a little more complicated question like "how to add table header on each printed page", but, anyway the way of solution is the same. Hope it's ok.

But there is several tricks to do what you want.

1) Break table in several parts, add thead part to each of them and remove margin, so it will looks like just one table. Add in css something like:

table {
    page-break-inside: avoid;
    page-break-after: auto;
}

table + table thead {
    display: none;
}

Also do not forget to set td width, cause tables without thead can have different width's.

After that add print styles:

@media print {
    table + table thead {
        display: table-column-group;
    }
}

Yep, there is a chance for duplicate headers on page, but it still better than nothing. And if you find good number of lines for your project it will looks as you need

2) Prepare dedicated downloaded printable version of page with WKHTMLTOPDF, for example. So you can catch page breaks well, and add what you need. This option give max flexibility of output, but will take some time for support.

3) Calculate everything with JS. Print your page and analyze it — add some constants to js (height per page), and, when someone try to print — calculate page breaks, find closest element and add what you need.

Hope you got answer. Have a nice day.

like image 173
Zav Avatar answered Sep 20 '22 17:09

Zav


I was also looking for a way to apply styles to only the first and last rows of a table over a page break, but maybe for a different use case.

I needed to give my whole table a border, but not on the table rows, just the outside. The easy way is to add a border to the table, but when a page break occurs, the borders aren't redrawn at the break.

My solution was to use a thead and tfoot, as these elements are repeated at every break. This gave me a full border around the table that obeyed page breaks.

You can modify this technique for your circumstances. Say if you wanted to change the styles of just the first row (and have it be consistent across page breaks), you just put that row in the thead or the tfoot depending on if you want the first or last row. You can even do this with an existing thead. Just give each thead tr a class so you know which is the main header, and which is a styled row.

There were a few caveats. The table footer had to have something within its tds otherwise it won't render. I added a &nbsp; (which means "no breaking space") to the first td and then set the font-size on the td to 1px (Otherwise there will be a noticeable gap at the bottom of your table). The font size has to be applied directly to the td. A font size of 0 will not work either. It has to be non-zero.

Example

This example is for my use case, but you can modify it. You can also use as many columns as you want. I used one for simplicity. The thead and tfoot must have the same number of columns though.

.my-table tr {border-left: 1px; border-right: 1px;}
.my-table thead {border-top: 1px;}
.my-table tfoot {border-bottom: 1px;}

// must be applied to the td!!!
.my-table tfoot td {font-size: 1px;}

<table class="my-table">
  <thead><td></td></thead>
  <tbody>
    <tr><td>data</td></tr>
    <tr><td>data</td></tr>
  </tbody>
  <tfoot><td>&nbsp;</td></tfoot>
</table>
like image 30
AlexMorley-Finch Avatar answered Sep 21 '22 17:09

AlexMorley-Finch