Saturday, January 13, 2007

Make Every Web Page Printer friendly

You found an article online and want to print it to nicely punch thee holes on the side and store it with other useful stuff. Almost every site nowadays provides a printer-friendly page of this and that, but some sites don't and you're still stuck with staring at their printed navigation bar, footer, ads, etc, for ever and ever. All this online decor means nothing on paper. How do you strip page parts that are irrelevant for print?

What we've acquired with the electronic age is an unquenchable thirst for printing. The bigger the online archives the more we print. I think no PDAs or TabletPCs will change this trend.

The Print Media

The CSS standard defines a number of media types. Among them are screen and print. The screen type is intended for computer screens. The content styled for this media type is what you see in your browser window. The print media is for screen print previews and actual printing.

The trick here is to define two stylesheets for your site:

  • one for screen
  • one for print

Trimming The Template

It's easier to design a stylesheet for printing if your site follows some templated layout. There are different ways to apply page templates in ASP.NET and there's enough information about it on the web. To start off, you need to hide whatever loses sense on paper, namely: navigation, menus, footers (unless you absolutely want to retain copyrights and disclaimers), etc. You can hide them with a simple CSS declaration.

For example, you have a <div> with navigation at the top of each page. Provided its ID is nav you write the following CSS rule:

#nav {
display: none;
}

This rule takes the navigation bar out of the page flow and hides it. Along the same lines you remove other page elements.

As a personal suggestion: hide banners and ads. For example, if you have several <div> tags with class="adv", remove them the same way:

.adv {
display: none;
}

Most likely you get paid per click, not per print-and-annoy. I can't click your banner or ad. Even if I see a Google Ad hyperlink I still can't click it. Besides, the idea of looking at advertisements forever doesn't excite me.

By now you should hide everything you don't want to appear on a printed page.

Change Colors

I suggest you give the content a white background and make the text black. There's no purpose in leaving color (unless you target color printers for some reason). Besides, printers won't print your color background anyway. Remember to also remove background images and watermarks the same way.

body {
background: white;
color: black;
}

A few words about hyperlinks. When printed their styles won't matter. What difference does it make if you assigned a different color to hovered links? Therefore you can safely drop hovers altogether. There's a neat trick to style hyperlinks even further. We'll get to it in a minute.

Change Units

It's a widely held belief that using points with fonts is a very bad idea when designing for the web. Pixels, ems, percentages beat points on the screen. However, when you design a stylesheet for print pixels become a lot less useful and points make perfect sense. Therefore we express font sizes in points here:

body {
background: white;
color: black;
font: 11pt;
}
Still not convinced about the usefulness of points? Eric Meyer provides an excellent explanation of why points fit the bill for print:

Points are real-worlds measures, like inches or meters. There are 72 points to an inch, which makes 12 points one-sixth of an inch. It's a fairly standard text measure in print, and we're working in print now. Print, being a physical medium, is an excellent place to use physical measures like centimeters, picas, or points. That's how points suddenly become useful—and, by implication, how pixels suddenly become a lot less useful.

That's because there's no clearly defined mapping between pixels and the physical world. How many pixels should there be per inch? Some claim it should be 72ppi, but others hold out for 90ppi, 75ppi, or some other number. So when we go to print, which is a physical medium, pixels become a lot less useful than they are on screen.

Source: Eric Meyer on CSS, Project 6 "Styling For Print".

Exercise sound judgment when it comes to font size. I find some sites overzealous as they choose font that is too large. You print a small article and it spreads out over a dozen pages. Try a couple of different sizes with your fonts.

Adjust Width, Height And Margins

It's good style to not stretch your text across the entire screen because it becomes daunting to read it. Most designs go for 760px which looks just right on monitors with the 800x600 resolution. I prefer to clear out the width on the content and let default printer margins kick in. If the text is too wide, add some right and left margins. Using padding is risky since some browsers don't always play by the rules when it comes to padding.

Linking Print Stylesheet

Remember to link the screen stylesheet with the media="screen" attribute:

<link rel="stylesheet" type="text/css" href="screen.css"
media="screen" />

What happens if you omit this attribute? The stylesheet will apply to all (!) media, including print. This may lead to conflicts in rule definitions in the screen and print stylesheets with one taking over the other. Ideally you should have this:

<link rel="stylesheet" type="text/css" href="screen.css"
media="screen"/>
<link rel="stylesheet" type="text/css" href="print.css"
media="print"/>

Styling Hyperlinks

A bit of underlined text signifying a hyperlink is of little use in print. One neat trick CSS-compliant browsers can do is insert generated content. We can insert the URL of each link right after it in parenthesis:
a {
color: inherit;
text-decoration: none;
}

a:link, a:visited {
text-decoration: underline;
}

#main a:link:after,
#main a:visited:after {
font-size: 85%;
content: " [" attr(href) "]";
text-decoration: none;
}

#main a[href^="/"]:after {
content: " [http://www.yoursite.com" attr(href)
"]"
;
}

#main a[href^="javascript:"]:after {
content: " ";
}

This approach is used extensively at Netscape Devedge. If a hyperlink starts with a forward slash (/) the url of your site (www.yoursite.com) is prepended automatically. If it's a hyperlink which invokes some JavaScript code nothing is appended.

As of the time of this writing, and for the foreseeable future, Internet Explorer 6.0 is not fully CSS compliant and misses some really important bits and pieces of the CSS specification. Generated content is one of them. Therefore IE will ignore all these hyperlink decorations and your users will have to put up with printed hyperlinks that don't even show where they lead. Shame. Try printing in Opera of Mozilla Firefox and links will have their URLs appended.

Check Your Progress

Printing a page at a time to see how your stylesheet is coming together is a major hassle. To debug your print stylesheet you need to switch the two temporarily. You can change the stylesheet intended for screen to something that is not supported, such as tty. At the same time you edit the print stylesheet link as follows:

<link rel="stylesheet" type="text/css" href="screen.css"
media="tty" />

<link rel="stylesheet" type="text/css" href="print.css"
media="screen" />
With this change your print stylesheet will be used to style content on the screen. Instead of printing to verify your progress all you have to do is refresh the page! Remember to change media types back when you're done.

Are We There Yet?

Did we get it perfect? No. Feel free to add more stylistic tweaks to your print stylesheets. What I described here should suffice for most sites, though. For more ideas see CSS Design: Going to Print at A List Apart.


Also, Derek Featherstone outlines an interesting technique to style any web site
out there to your liking. See his article Print It Your Way.

The End Result

In the end you should have every web page being printer-friendly. You don't have to devise any special "printer-friendly" pages. The benefits should be clear: (1) simpler code maintenance since you do not need to maintain separate "printer-friendly" pages, and (2) happier users since they don't have to wade through meaningless content.