Printer Friendly Pages

swnesbitt - 2006-05-17 05:56:07 in CSS
Category: CSS
Reviewed by: swnesbitt   
Reviewed on: May 26 2006

Technologies like the Web are supposed to make us paperless. But that's not the case at all. If anything, people print Web pages almost as often as they read them on screen. Why? Most people are tactile. The heft of paper is comforting to them. In fact, several people have told me that a document isn't "real" if they can't hold it in their hands.

In many instances, printed Web pages look like ... well, printed Web pages. There's a lot of superfluous content in the printout. Depending on the page, that could include navigation bars, ads, icons, etc. On top of that, the text on many a Web page scrolls beyond the right margin, and words are cut off in the hard copy.

Countless Web sites allow you to access "printer friendly" versions of their pages. However, these are usually generated using some server-side arcana. Instead of using scripting, why not use CSS to create printer-friendly Web pages?

Among other things, the Cascading Style Sheets, Level 2 specification defines how to target some or all of a a Web page to a particular output device -- media in CSS-speak. One of those media is a printer. Using CSS, you can reformat your Web pages for printing. And if you've coded those pages properly the process of styling for print is quite easy.

Let's Get Styling!

Before you start coding your print styles, you should decide how you're going to put those styles into a CSS file. There are two ways you can put CSS printing styles into a file:

How you combine or separate styles will affect how you link your stylesheet to your Web pages (this is discussed later in the article). If you plan to combine your screen and print styles in a global CSS file, you must create a section for each set of styles. Set up the screen styles section like this:

[code] @media screen {


}[/code]

Set up the print styles section like this:

[code] @media print {


} [/code]

The @media elements are the way that CSS tells a browser when and where to apply formatting. You simply put your style definitions for each media between the curly braces.

Building the Stylesheet

Let's assume that the Web pages you want to style for print contain elements that you don't want to appear on a printed page. What kinds of elements? Navigation menus, ads, graphical headings, and the like. You'll quickly learn to love the display: none property. display: none tells a CSS-capable browser not to render any element that it's applied to. So, if your Web site is designed with CSS and you have an area for your navigation menu defined as div#navBar, then in your print stylesheet or print section of your global stylesheet, you'd add the following definition:

[code] div#navbar {display: none} [/code]

Note: For more information on designing Web sites with CSS, see the DEVPEN article "Two and Three Column Layouts with CSS".

Apply display: none to every section of the page and/or every element that you don't want printed.

But what do you do if your pages aren't designed with CSS? Say, for example, you use tables for the layout of your Web pages? Here's a little trick that you can use. Tag each part of the table that you don't want printed with a class called .content, for example:

[code] <td class="content">
... your content here ...
</td> [/code]

Then, in your print stylesheet or print section of your global stylesheet add the following CSS property:

[code] .content {display: none} [/code]

The parts of the table that are tagged with .content the won't appear when someone prints a page.

Note: Although I used .content to name that class, you can call it anything that's meaningful to you.

Your Web pages will most likely be made up of a number of common HTML elements. In this article, I'll discuss how to style the following elements for print:

Note: You're not limited to styling the above HTML elements. Feel free to experiment with styling lists, tables, images, font elements (like <code> and <em>), etc. for print.

First, let's set up the style for the <body> tag:

[code] body {margin-left: 30px;
font-family: sans-serif;
font-size: medium;
padding: 6px;} [/code]

The margin-left: 30px property indents the all elements of the Web page 30 pixels from the left margin. This adds a nice effect to print documents, especially when combined with the styling that we're going to add to the headings.

The font-family: sans-serif property sets all body text to a sans-serif font. Many old-school typesetters insist that in printed documents, headings be in a sans-serif font (like Helvetica) and body text be in a serif font (like Times). I don't believe that this is a hard and fast rule. Experiment with different fonts. But your font choices should be made on the basis of readability, not how cool you might think the font is. And remember that the font you specify for the <body> will affect all elements contained in the body of your Web pages: paragraphs, list items, table cells, etc.

The font-size: medium property sets the font size to about 12 points, the size of the type in a newspaper or magazine. That's quite legible, but if you think the font is too large you can change the size to small.

I included the padding: 6px property to add a bit of space around the margins. You can add this style to your screen stylesheet, too.

Moving on to the heading styles, let's start with <h1>:

[code] h1 {margin-left: -25px;
font-family: sans-serif} [/code]

Again, the font used is sans-serif -- I think that heading in a serif font looks a bit too staid whether in print or on the Web.

Notice, though, that I set the margin-left property to -25 pixels. This creates with effect that I alluded to earlier. All headings that are tagged as <h1> will be 25 pixels to the left of the body text. This effect is called an outdent, and looks like this:

Outdent example

In many structured documents, not all headings are outdented to the same degree. A first level heading has the largest outdent, and all other headings move to the right. Using that as a guideline, let's style <h2> like this:

[code] h2 {margin-left: -15px;
font-family: sans-serif} [/code]

The outdent for <h2> is five pixels smaller than for <h1>. The font is, you guessed it, sans-serif.

Now, for <h3> and <h4>. Some people like to have <h3> outdented and <h4> in line with the body text. Not me. I like them both in line with body text. So, here's how to create that effect:

[code] h3, h4 {font-family: sans-serif} [/code]

Notice that I didn't include a margin-left property with this style definition. It's not needed. Both the <h3> and <h4> will automatically be in line with the body text.

Adding Page Breaks

Web browsers don't add page breaks very well. If you've ever printed a Web page, you've probably seen (for example) a heading on the bottom of a page, and the text that goes with it on the next page. You can avoid this by using the following CSS property:

[code] page-break-before: always [/code]

As you can probably guess from the name of the property, it adds a page break above the element to which it is applied. You'll want to use page-break-before: always sparingly. Most people I know who use the page-break-before: always property usually apply it to the <h2> element.

When you're testing your print-only pages, you may find that you need to force page breaks at certain point in a document. In the word processing world, these are called hard page breaks. To add a hard page break to any HTML element, just define this class in your stylesheet:

[code] .breakPage {page-break-before: always} [/code]

Then, apply it a tag like this:

[code] <p class="breakPage"> ... your content here ... > [/code]

Once you have created your stylesheet, it's time to link it your Web pages. If you combined the screen and printing stylesheets in one CSS file, simply add something like the following to the header of your HTML files:

[code] [/code]

If, on the other hand, you have your print styles in a separate CSS file, add something like the following to the header of your HTML file:

[code] [/code]

The media="print" attribute tells the browser to apply the stylesheet myPrint.css whenever a Web page is sent to a printer. Remember also to link your screen CSS file to the Web page in the same way. For the screen stylesheet, however, specify media="screen" instead of media="print".

There are two ways that you can test your print styles. The most obvious one is to actually print a page. But doing this wastes paper and printer ink. A better way is to use your Web browser's print preview feature. In most browsers, regardless of the operating system on which they're used, Print Preview is found under the File menu.

A page that uses the stylesheet we created earlier looks like this in a CSS-capable browser's print preview:

Sample print preview in Opera

You might have to fiddle with your stylesheet to get it looking just right for print. If possible test it under as many CSS-capable browsers as possible.

Conclusion

Creating printer-friendly versions of your Web pages doesn't require a lot of fiddling on the server side of things. Using CSS, you can easily and quickly retrofit your existing Web pages. You'll no longer need a "Print this page" or "Printer-Friendly Version" button or link on your pages. Visitors to your Web site will just have click the Print icon in their browsers and they'll get a nicely-formatted hard copy of your Web content.