If you are exclusively supporting Firefox, the solution is quite straightforward. (To view an alternative technique that also functions in IE but with limited versatility, skip to the edit section. At the time of this answer, Chrome and other webkit browsers did not support repeating footers)
All you need to do is add a substantial bottom margin at the end of your content. The exact size does not have to be precise, but it should be large enough to extend past the end of the page. It is recommended to make it at least as big as the maximum paper size your users might use.
Do not worry, adding this margin will not result in a blank page at the end of your document. Margins behave differently from other white space forms (like padding and <br>
tags) as they cancel out when surpassing the page boundary (see spec, section 13.3.3). While both Firefox and IE discard the margin, Firefox still generates a footer at the page's bottom as if a page break has occurred. On the contrary, IE acts as if the margin never existed, hence why this method fails in that browser.)
To keep your HTML clean, you can place the margin on a pseudo-element. Additionally, you can utilize @media print
to prevent it from displaying on the screen.
Below is the code snippet. To witness its functionality in Firefox, access this jsfiddle, right-click on the output, choose This Frame > Show Only This Frame, and initiate a print preview.
@media print {
#content:after {
display: block;
content: "";
margin-bottom: 594mm; /* must exceed largest paper size supported */
}
}
<table>
<thead>
<tr>
<th>PAGE HEADER</th>
</tr>
</thead>
<tfoot>
<tr>
<td>PAGE FOOTER</td>
</tr>
</tfoot>
<tbody>
<tr>
<td id="content">
content<br>content<br>content<br>content<br>content<br>content<br>content<br>
content<br>content<br>content<br>content<br>content<br>content<br>content<br>
content<br>content<br>content<br>content<br>content<br>content<br>content<br>
content<br>content<br>content<br>content<br>content<br>content<br>content<br>
content<br>content<br>content<br>content<br>content<br>content<br>content<br>
content<br>content<br>content<br>...
</td>
</tr>
</tbody>
</table>
EDIT
An alternate approach that is effective in both Firefox and IE involves placing the footer in a separate <div>
fixed at the bottom of the page, utilizing the repeating <tfoot>
as a spacer. However, there are some minor drawbacks to this method (explained below the snippet).
The following code illustrates this technique. To observe it functioning in Firefox, visit this jsfiddle, right-click the output, select This Frame > Show Only This Frame, and proceed to a print preview. In IE, click within the output frame, press CTRL+A, open a print preview, and switch "As Laid Out On Screen" to "As Selected On Screen".
@media print {
#spacer {height: 2em;} /* footer height + extra space */
#footer {
position: fixed;
bottom: 0;
}
}
<table>
<thead>
<tr>
<th>PAGE HEADER</th>
</tr>
<thead>
<tfoot>
<tr>
<td id="spacer"></td>
</tr>
<tfoot>
<tbody>
<tr>
<td>
content<br>content<br>content<br>content<br>content<br>content<br>content<br>
content<br>content<br>content<br>content<br>content<br>content<br>content<br>
content<br>content<br>content<br>content<br>content<br>content<br>content<br>
content<br>content<br>content<br>content<br>content<br>content<br>content<br>
content<br>content<br>content<br>content<br>content<br>content<br>content...
</td>
</tr>
</tbody>
</table>
<div id="footer">
PAGE FOOTER
</div>
A limitation of this method is that it places an identical footer on every page within the print job, meaning different footers or no footer for certain pages are not possible. Also, since the spacer's height depends on the footer's height, adjustments will be required if the footer height changes.