Hire a web Developer and Designer to upgrade and boost your online presence with cutting edge Technologies

Saturday, November 19, 2011

Things I Learned About Print Stylesheets From HTML5 Boilerplate

screenshot
Print stylesheets can be a pain if you don’t know what you’re doing. Before you even approach one you need to make sure to do some solid research into how to go about it.
Today we’re going to help you along by first discussing the conceptual considerations that you need to keep in mind when creating a print stylesheet. Then we’ll dive into some code from the famous HTML5 Boilerplate to see some modern solutions for addressing the problems that arise when printing from the web.


Where Web Design Meets Print

The web and print are two fundamentally different beasts. They’re so different that you’ll often find designers who work full time in one medium or the other with almost no cross over. As a result, print designers often know very little about web design and web designers know very little about print design.
However, interestingly enough, most experts call for a little bit of overlap in every single web project you create. We’re of course talking about print stylesheets, which result in a sort of bizarro world where CSS is being used to design for print! It’s a crazy scenario, but you’re expected to plan for it nevertheless.
Unfortunately, even if you know your way around CSS fairly well, print stylesheets can throw you some curveballs. There are quite a few quirky tricks that you’ll need to implement in addition to plenty of conceptual planning.
Let’s see how to start this process by asking a few key questions.

Print vs. Web: What Are the Fundamental Differences?

This is an important question to ask yourself when creating a print stylesheet. After all, you’re converting a design from one medium to another so it pays to give some thought to how they differ.
“You’re converting a design from one medium to another so it pays to give some thought to how they differ”
Let’s think about the obvious areas. First of all, a page is a very limited canvas. Websites represent a fairly infinite space that can scroll as far as you want in any direction. Physical pages however, are stuck at 8.5″ by 11″ with a printable area of even less than that.
This has major implications. It means that lengthy content will eat up tons of paper. This leads us to think about where we can cut back. For instance, if we’re printing articles with hundreds of comments, maybe we should turn those off. There’s also an obvious change that must be made to the width of our content. Both the copy and the images need to be sized appropriately.

Interaction

Another major difference between print and the web is the capacity for interaction. The web represents a richly interactive dynamic medium while print is static; what’s on the paper is stuck there!
This means you need to rethink any interactive elements on the page. For instance, navigation menus are usually one of the first things to go. A printed page has no use for them and they can really eat up space if converted to simple unordered lists.
“You need a good way to take all those inline links and show the reader where they lead”
You also have to consider what’s going to happen with image sliders and the like. If your page has a slideshow with ten images at the top, that’s not going to translate well to paper.
The most basic level of interaction on the web is a link. This too becomes problematic. On your computer, you can simply click a link to see where it goes, on paper this functionality is lost so you need a good way to take all those inline links and show the reader where they lead.

Who is Printing this Page and Why?

The second important question that needs to be asked relates to why the page is being printed in the first place. A good designer doesn’t just set out to make things look good, the design has to maximize utility for the user.
“A good designer doesn’t just set out to make things look good, the design has to maximize utility for the user.”
This of course means that you have to consider just what the typical user wants. This isn’t going to be a universal answer. Every type of project will have a unique use for the printed page.
For instance, Google Maps users want just about everything stripped off the page for print: ads, the huge interactive map, the Google search bar, all of this and more must be ditched for a clean list of readable directions.
These goals are obviously quite different from someone who prints out a design blog post to circulate around at a meeting as a discussion point. Here the emphasis is on presentation of lots of text rather than very little.

Learning By Example: HTML5 Boilerplate

screenshot
When you’re working with types of CSS that you’ve never approached before, one of the best possible ways to learn is to simply look around and see what others are doing.
The first place I usually start in cases like this is Paul Irish’s HTML5 Boilterplate. This project is a rock solid collaboration from leading industry professionals. It’s not by any means infallible but it’s still a great example to learn from.
If we download the Boilerplate and crack open the CSS file, we find the print styles at the very bottom:
@media print {
  * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; } /* Black prints faster: h5bp.com/s */
  a, a:visited { text-decoration: underline; }
  a[href]:after { content: " (" attr(href) ")"; }
  abbr[title]:after { content: " (" attr(title) ")"; }
  .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }  /* Don't show links for images, or javascript/internal links */
  pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
  thead { display: table-header-group; } /* h5bp.com/t */
  tr, img { page-break-inside: avoid; }
  img { max-width: 100% !important; }
  @page { margin: 0.5cm; }
  p, h2, h3 { orphans: 3; widows: 3; }
  h2, h3 { page-break-after: avoid; }


This fairly small chunk of code has a lot going on, which means there’s plenty to learn from. Let’s dive in and see what we can find.
Print Media Query

This fairly small chunk of code has a lot going on, which means there’s plenty to learn from. Let’s dive in and see what we can find.

Print Media Query

@media print {}
The very first thing you should notice is the use of a media query to specify the print styles. This tells the browser that all the styles contained in this block are only to be applied under a special circumstance, in this case a user printing the page (this will help end the old “click for printer friendly version” technique).

Universal Selector and Blanket Styles

* { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; }
The next thing I notice is that the universal selector (*) is immediately whipped out to apply some blanket style changes to the page.
The result here is a drastic simplification of the visual styles on the page. Any background image or color is turned off, the text color is turned to black, text-shadows are disabled, etc. All of this both improves readability and saves on ink.

Print Friendly Links

a, a:visited { text-decoration: underline; }
  a[href]:after { content: " (" attr(href) ")"; }
  abbr[title]:after { content: " (" attr(title) ")"; }
  .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }  /* Don't show links for images, or javascript/internal links */
Remember we said above that something would have to be done about printed links? It turns out that you can handle this task using pure CSS, an impressive feat! Good old Eric Meyer was doing this way back in 2002 on A List Apart’s CSS Design: Going to Print.
After first applying an underline to all the links on the page to help them stand out (some slightly change the color as well), there’s a snippet of code applied that actually prints out the link after the text:
a[href]:after { content: " (" attr(href) ")"; }
The result is that a typical link will be changed to link (http://goo.gl/CWGL4). As you can see, this is perfect for a printout. As a side note, not all browsers will support the CSS above, but those that won’t will print just fine, only without the parenthetical link text thrown in.
Notice that the Boilerplate goes one step further by disabling this action on images and JavaScript containing links.

Optimizing Page Breaks

You’ll notice plenty of code for dealing with page breaks: page-break-after: avoid; and p, h2, h3 { orphans: 3; widows: 3; } are both aimed at helping the pages flow better. The former forbids a page break directly after headers and paragraphs where possible, the latter ensures that no less than three lines can be orphaned or widowed on a page.
What are orphans and widows? When you have the first line of a paragraph stranded alone at the bottom of a page, that’s an orphan. Similarly, the last line of a paragraph may be carried over by itself to the next page, this is a widow. The code above ensures that, where possible, at least three lines of text will appear.

Image Sizing

img { max-width: 100% !important; }
Setting the image maximum width to 100% ensures that you don’t have any weird bleeding images. You’ve probably run into this before as a user: you go to print a web page and end up with several pages containing only partial images that were cutoff from the main page. This is easily preventable with the single line of code above!

Page Margins

@page { margin: 0.5cm; }
The way that the HTML5 Boilerplate defines page margins is very interesting. Most older articles about print stylesheets include very different methods. In fact, I didn’t even know about this method until writing this article.
It turns out that you can use @page to simply apply a margin all the way around the page. The code above applies a margin of 0.5cm (centimeters is CSS? Oh my!) to all pages uniformly.
If you want to get tricky, you can modify this to adjust the settings for every other page. The following code sets the left page (1, 3, 5, etc.) and right page (2, 4, 6, etc.) margins independently.
@page :left{ margin: 0.5cm; }
@page :right{ margin: 0.8cm; }
It’s a simple and elegant solution that is, surprisingly enough, CSS2.

Further Reading

Since HTML5 Boilerplate is a generic template, it doesn’t contain many of the code snippets that are typical of very specific types of sites like blogs. Before attacking your own print stylesheet project, browse a few of the following articles to make sure you’re up to speed.

Conclusion

Print stylesheets represent a completely different way to think about and use CSS. They’re not always the most intuitive of tasks so don’t expect to intuitively land on the right answers. Be sure to do your homework and test extensively.
Do you have any tricks or best practices regarding print stylesheets? Let us know in the comments below!

No comments:

Post a Comment