Enterprise Software

Use styles to dynamically create headers, footers, and page breaks

If you want to force widths and page breaks on an HTML page, Phillip Perkins explains how you can do it. He walks you through the process of creating the headers and footers necessary to dynamically insert these items to create a formatted hardcopy.

While perusing a discussion board, I read a question from a concerned developer who was trying to programmatically create headers and footers and insert page breaks on an HTML page. This is next to impossible considering what your output is, since there's no easy way to figure out the browser's current settings for margins, page sizes, etc. However, if you want to force widths and page breaks, you can do it.

One way to accomplish this is to use TABLEs. In this article, I'll show you how to create the headers and footers necessary to dynamically insert these items to create a formatted hardcopy. (Note: I used IE 6.0 to test the code in this tip. It also works on 5.0 and above, because I use the @media pseudo-class available for the STYLE element in IE since 5.0.)

The easiest way to create this functionality is to use TABLEs. However, your formatted output must contain individual rows that don't exceed the printed page's height. Also, your TABLE must not exceed the width of the printed page. Since you don't have any control over landscape or portrait, you must make some assumptions. You'll assume that the orientation of the document is portrait with 1" margins left and right, 0.25" margins top and bottom, and the paper size is 8.5" X 11". This means that you have 6.5" total width for output, so your TABLE width will be set to 6.5in, no border. At the top of the table, you're going to create two hidden DIVs that will serve as the header and footer. The DIVs have set widths and heights, and the overflow style attribute is set to hidden. This sets the foundation for your output. In order to create the page breaks, headers, and footers, you'll have to incorporate some JavaScript after the page loads.

The idea for creating the formatted output is to copy the header and footer DIVS into hidden rows. However, you'll set the display style attribute to inline for @media print. Also, you'll set the page-break-after style attribute to always for the TR just before the footer.

During the BODY onload event, iterate through all the rows to determine whether the row offsetTop plus the offsetHeight exceeds the available length of the page. The available length is the length of the page minus the sum of the heights of the header, footer, and top and bottom margins. So, if the header height and footer heights are each 1", the top and bottom margins are 0.25", and the page length is 11", then the available width is 8.5": 11 - (1 x 2) - (0.25 x 2) = 8.5.

Listing A contains the HTML that accomplishes this task. When you examine the sample code, you'll notice that the header and footer are two hidden DIVs that appear right before the TABLE element. The TABLE tbl1 contains multiple TRs. Each of the rows is identified as t1 to help iterate through them using the all collection. This example will only work with two or more rows. I create the style class hdrftr to identify when those items should be displayed. The JavaScript details how the functionality is created.

First, a header row is added to the top of the table. Next, each row is examined to determine if the top coordinate plus the row height plus the footer height — 1in * screen.deviceYDPI or just screen.deviceYDPI — meets or exceeds the total available height. If this value matches the available height, the current row is set to have a page break after it. If this value exceeds the available height, the previous row is set. The row of interest is then used to append a footer row after it and a header row is added after the footer row. This process continues until all rows are examined. Finally, a footer row is appended to the end of the table. The footer row contains absolute positioning to avoid inadvertent page-breaks from the browser, thus giving us a little margin of error. Also, each subsequent page must make a provision for the additional header rows that we add: (page - 1) * 1, where (page - 1) is the subsequent page number and 1 is the height of the header.

Keep your developer skills sharp by automatically signing up for TechRepublic's free Web Development Zone newsletter, delivered each Tuesday.

Editor's Picks

Free Newsletters, In your Inbox