css printer formating
It is common practice when creating a website that displays useful data to people, to want to print that data. When the
data contains charts(tables) or images ect. it is annoying to find that your data lies between where your printer formats a
page. On a professional site your clients will often want to print this data for meetings and such. This lack of formating
quickly becomes unacceptable. At first glance you will do a bit of homework on this problem and notice that css has provided
some ways of dealing with this.
page-break-after
page-break-before
Both commands have four attributes that you may use. The attributes are as follows:
- always tells the browser to break the print page after this element always.
- auto is the default. You're telling the browser to do what it would do anyway: Page break where the page ends.
- left is not supported by any browser yet. It is used if your printer will print both sides of a page,
like a manuscript. If the page is a left-facing page, use this attribute.
- right is what you use if it's a right-facing page.
This allows us to specify styles for elements like this.
H1{
page-break-before: always;
}
This above line would tell the printer that every <h1> tag should occur on a new page. So this will allow us to
run around on a static page we have designed entering page breaks on any elements that we feel are necessary. GREAT ... uh not really.
What we really want is to be able to have all our dynamically generated content formated in some logical manor. For example if we
generate a page with a variable amount of content that has tables of data mixed in with it, we don't want page breaks to happen on
our tables. For these we find another css attribute that may help.
page-break-inside
This element has the same four properties as above and is used to tell out printer what should happen inside an element.
The problem with it.... IS IT DOESNT WORK !!!. As of the time of writing this IE 6 does not seem to care if this tag is in
your document. This really sucks and if anyone has got it to work please send me an example with your code.
Solution
Well now there are a few things we can do about this. We know that the page-break-before and page-break-after do work. So
we could write a script to find out if items that we dont want to break occur on a page boundary. Then we could force a break
before this element
Stated once again for clarity, the algorithm is something like this.
- Figure out the height of your page (usually 800px for normal printer paper)
- Find the items that you don't want to break and give them all ids of some sort.
- We need to see if the top of this item + the size of it will put it on a page boundary.
- If so then we will force a page break before the item and adjust our heights accordingly.
Here is a simple example where we just check if our paragraph tag <p> is on a page boundary. If it is
we then modify it accordingly. This is a very simple script but should serve as a good starting point to tailor one
that is more specific.
<script language="javascript">
var pageHeight = 800;
var allP;
function doPageBreaks()
{
var allP = document.getElementsByTagName("P");
for( var i=0; i < allP.length; i++ )
{
var p = allP[i];
if ( (p.offsetTop - pageHeight) > 0 )
{
p.style.pageBreakBefore = "always";
pageHeight+=pageHeight;
}
}
}
</script>
If anyone has a better way of doing this please let me know by email: corey(at)coreyauger.com . I realize that this is a hack (:
|