CSS Print Media Page Headers and Footers

By Gord at June 01, 2011 11:31
Filed Under: ASP.NET, JQuery

After spending a couple days looking for a way to get a browser to print a pages with a header and footer on each page, I finally compiled a list of things that will certainly help most people.

 

I’m going to assume that you already know something about the @media CSS tags.  So I won’t go into the differences between the @media print and @media screen etc.

 

The two method below work, but have some limitations.  The final solution for most people would be using method 2 for the header, and method 1 for the footer.

 

Method 1: div tag header and footers

 

div.header
{
position:fixed;
top:0px;
width:98%;
display:block;
}

div.footer
{
width:98%;
position:fixed;
bottom:0px;
}

This method has a couple drawbacks.

1) The “meat” of your printed page will need to have a “margin-top” that is equal to or greater than your header

2) Due to CSS 2.1 implementation and the lack of CSS3 support, your “margin-top” will get reset to 0 on the second page resulting in overlap of your content with your header.  The only way around this is if you force page breaks on your own and specify a “margin-bottom” like the example below:

div.pageBreak
{
page-break-after: always;
}
 
 
Method 2: tables?!
Yes, tables work great for this situation.  I found this out by chance on stack overflow: <link here>.
 
Your CSS will look like this:
thead { display: table-header-group; }
tfoot { display: table-footer-group; }
 
Your HTML will look like this:
<body>
<table>
<thead><tr><td>Your header goes here</td></tr></thead>
<tbody>
<tr><td>
Page body in here -- as long as it needs to be
</td></tr>
</tbody>
<tfoot><tr><td>Your footer goes here</td></tr></tfoot>
</table>
</body>
 
A few minor drawbacks to this method as well
1) Your footer won’t always be at the bottom of the page.  If your content ends half way down the page, that’s where you footer will be.  I’d suggest using the METHOD 1 footer method in this case.
2) If you are using div tags inside the content section, in IE they get truncated in a strange way.  The div will get cut and shrunk onto the one page, but the remainder loses it’s formatting when it travels to the next page.  I’m still looking at methods around this weird bug.
 
** update for method 2**
If you do end up having issues with truncation and weird behavior after your first page you'll need to set your div tags to function as part of the table.  ie:  use the CSS tags: display:table-cell or display:table-row in conjunction with page-break-inside:avoid; page-break-before:auto for any data inside the table body.
 
For example, this HTML code would be repeating over and over again inside the “page body in here” section from the code above.
<div class="myrepeatingdata">
<div class="mydivtable">
<div class="myrow">
<div class="mycol1">LEFT</div>
<div class="mycol2">MIDDLE</div>
<div class="mycol3">RIGHT</div>
</div>
</div>
</div>

The CSS would look similar to this:
div.myrepeatingdata
{
border: 2px solid grey;
margin-top:15px;
page-break-before: auto;
page-break-inside: avoid;
width:99%;
display:table;
}
div.mydivtable
{
display:table-row;
padding-top:5px;
padding-bottom:5px;
}
div.mycol1
{
width:40px;
height:100%;
padding-left:3px;
display:table-cell;
}

div.mycol2
{
width:150px;
height:100%;
display:table-cell;
}

div.mycol3
{
width:auto;
height:100%;
display:table-cell;
}


 

About the author

Gord graduated from Carleton University with a bachelors of Computer Science with minors in both Philosophy and Mathematics.  His post graduate career started in 2005 as a Systems Administrator until becoming a .Net Web Developer 2 years later.  Since then, he has moved on to being a more generic Systems Developer, focusing on intersystem communication, design, and architecture.

Page List