Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controlling CSS page breaks when printing in Webkit

Tags:

html

css

webkit

I'm attempting to improve the appearance of html documents printed using Webkit, in this case by exerting some control over where page breaks occur.

I'm able to insert page breaks where I need using:

page-break-after: always; 

However, I can't find a way to avoid page breaks being inserted in the middle of items. For example, I have html tables that should not be split in the middle across multiple pages. I had the impression that

page-break-inside: avoid;

would prevent a page break from being inserted inside the element, but it doesn't seem to be doing anything. My code looks like:

.dontsplit { border: 2px solid black; page-break-inside: avoid; }

<table class="dontsplit">
    <tr><td>Some title</td></tr>
    <tr><td><img src="something.jpg"></td></tr>
</table>

Despite the page-break-inside: avoid directive I still get the table split between the first and second row into separate pages.

Any ideas?

like image 650
Parand Avatar asked Oct 08 '09 19:10

Parand


People also ask

How do I avoid a page-break inside?

The page-break-inside property sets whether a page-break should be avoided inside 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 absolutely positioned elements.

How do I prevent a page-break in a div?

Syntax: page-break-inside: auto; avoid: It avoids a page break inside the element.

Can I force a page-break in HTML printing?

We can add a page break tag with style "page-break-after: always" at the point where we want to introduce the pagebreak in the html page.

How do I stop an element from printing on two pages?

You can use page-break-inside="avoid" on <div> "B". This is probably closer to what you want. If "B" does not fit on the page with "A", "B" will all be moved to the next page.


2 Answers

Downloaded a recent binary of wkhtmltopdf http://code.google.com/p/wkhtmltopdf/, and the following seems to work.

.dontsplit { border: 2px solid black; page-break-inside: avoid; }

<table>
  <tr><td><div class="dontsplit">Some title</div></td></tr>
  <tr><td><div class="dontsplit"><img src="something.jpg"></div></td></tr>
</table>

reference: http://code.google.com/p/wkhtmltopdf/issues/detail?id=9#c21

Prudent to put margin, and padding to zero on the td, and place any on the div, otherwise you'll get "edges" making it over the folds

like image 146
Cliffordlife Avatar answered Sep 19 '22 14:09

Cliffordlife


As cliffordlife states,

.dontsplit { border: 2px solid black; page-break-inside: avoid; }

will work. But not for firefox. In firefox, what you are going to have to do is check for the height and then add page-break-after: always; when it is relevant.

On average, the margin will be 1 inch on top and bottom. So, to measure how many pixels a 10 inch page would consume, I used this:

var pageOfPixels;
(function(){
    var d = document.createElement("div");
    d.setAttribute("style", "height:9in;position:absolute;left:0px;top:0px;z-index:-5;");
    document.body.appendChild(d);
    pageOfPixels = $(d).height();
    d.parentNode.removeChild(d);
})();

I had a lot of divs each with a lot of paragraphs in them. So what I did was I iterated through them, and then compared the current height of the them on the current page to the pageOfPixels value.

var currentPosition = 0;
$('.printDiv').each(function (index, element) {
    var h = $(this).height();
    if (currentPosition + h > pageOfPixels) {
        //add page break
        $('.printDiv').eq(index - 1).css("page-break-after", "always");
        currentPosition = h;
    } else {
        currentPosition += h;
    }
});

This worked for me in firefox.

like image 40
Travis J Avatar answered Sep 17 '22 14:09

Travis J