Print to Preview
Issue № 226

Print to Preview

Remember in the old days when you had to effectively run two sites or create separate templates in a CMS for “printer friendly pages”? No one liked that. Then print stylesheets came along and everything became wonderful and easy. Except that the people who use our sites didn’t think so; in fact, most got a tad confused because suddenly the “print this page” button and the subsequent full screen preview disappeared on all but the largest of sites.

Article Continues Below

What’s happening now?#section2

Many sites have done away with the “print this page” button entirely. Most web designers expect site users to know how to print from the browser, and if they do offer a “print this page” button, clicking the button simply prints without a preview. There is, of course, a “preview” button in the print dialogue box but most people miss it, have forgotten about it, or don’t even know about it.

As Cameron Adams noted back in 2004, visitors aren’t familiar with print CSS and don’t see a print preview; they expect that when they print a web page, the design on screen will match the printed page—or at least be very similar. Readers of A List Apart know that the changes from screen stylesheets to print stylesheets can be dramatic. This is often by design, as we want to improve people’s paper-based experience by removing “unnecessary” elements such as navigation and advertising. However, these dramatic changes can make people uncertain how the printed page they have in their hands relates to the website they just visited.

Oh great—expectations#section3

So how do we set the right expection about our print version? Why, we switch stylesheets of course! We can create an alternate stylesheet to show how the page will look when it’s printed, perhaps display a preview message explaining what this new view is about, and then automatically print the page with the print stylesheet we know, love, and trust.

The building#section4

First we’ll swipe some of the code from an old ALA article, “Alternative Style: Working With Alternate Style Sheets”, namely this one. (Line wraps are marked ». – Editor)

setActiveStyleSheet(title){  // select the stylesheet
   var i, a, main;
   for(i=0; (a = document.getElementsByTagName("link") »
[ i ]); i++) {
     if(a.getAttribute("rel").indexOf("style") != -1
        && a.getAttribute("title")) {
       a.disabled = true;
       if(a.getAttribute("title") == title) a.disabled = »
false;
     }
   }
}

We then drop a couple of functions into our JavaScript file. These functions simply add a “print this page” link at the page load, “print preview” which switches to the print preview and automatically prints the page, “add preview message” which displays a preview message and finally ”cancel print preview” which allows users to return to the “normal view” of the site. (Line wraps are marked ». – Editor)

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

addLoadEvent(function() {
  /* more code to run on page load */
      if (document.getElementById){
        //     add extra functions to page tools list
        var print_page = document.getElementById('nav');                                                        

        //     create print link
        var print_function = document.createElement('p');
        // print_function.setAttribute('class', 'print');
            //IE doesn't like this
        var print_function_link = document. »
createElement('a');
            print_function_link.onclick = function() »
{ print_preview(); return false; }
            print_function_link.setAttribute('href', '#');    
        var print_function_link_text = »
document.createTextNode('Print the Page');

            print_function_link.appendChild »
(print_function_link_text);
            print_function.appendChild »
(print_function_link);            
            print_page.appendChild(print_function);            
    }
});

function print_preview() {
    // Switch the stylesheet
    setActiveStyleSheet('Print Preview');

    // Create preview message
    add_preview_message();

    // Print the page
    window.print();
}

function add_preview_message(){
var main_content = document.getElementById('content');
var main_body = main_content.parentNode;

    if (document.getElementById){

        var preview_message = document.createElement  »
('div');
        preview_message.id = 'preview-message';

        // Create Heading
        var preview_header = document.createElement('h3');
        var preview_header_text = document. »
createTextNode('This is a print preview of this page');
        preview_header.appendChild(preview_header_text);

        // Create paragraph
        var preview_para = document.createElement('p');
        var preview_para_text = document.createTextNode »
('Without this message of course. ');

        var cancel_function_link = document.  »
createElement('a');
            cancel_function_link.onclick = function() »
{ cancel_print_preview(); return false; };
            cancel_function_link.setAttribute('href',  »
 '#');    
        var cancel_function_link_text = document. »
createTextNode('Return to the existing page.');
        cancel_function_link.appendChild »
(cancel_function_link_text);
        preview_para.appendChild(preview_para_text); //
        preview_para.appendChild(cancel_function_link);

        // Put it all together
        preview_message.appendChild(preview_header); 
        preview_message.appendChild(preview_para);
        main_body.insertBefore(preview_message,  »
main_content);

    }
}

function cancel_print_preview() {
    // Destroy the preview message
    var print_preview = document.getElementById 
    ('preview-message');
    var main_body = print_preview.parentNode;
    main_body.removeChild(print_preview);

    // Switch back stylesheet
    setActiveStyleSheet('default');
}

Then we’ll add in the alternate stylesheet “Print Preview” to our HTML files.

<link rel="alternate stylesheet" type="text/css" href="css/print-preview.css" media="screen" title="Print Preview" />

The print preview stylesheet simply imports our existing print stylesheet and sets styles for the preview message.

@import "print.css";

#preview-message {
  display:block;
  border:1px solid #666;
  background:#eaeaea;
  padding:2px 5px;
}

This message is important because it provides context for the new “view.” Without it, the new stylesheet could be quite confusing to a visitor who clicks the preview link by accident.

An improved printing experience#section5

Here’s an example. Obviously, this is not the perfect technique for every site and you should probably do user testing and tweak the implementation on a case-by-case basis: you may find you need to display a “preparing print version” message for a few seconds before the style switch for some audiences, but not for others.

Now if we could only help people figure out which printer they’ve printed to and where that printer is…

About the Author

Pete McVicar

Pete McVicar is a freelance web designer/developer living in New Zealand. When not obsessing about web standards, he can be found scaring small children with his Alaskan malamute.

32 Reader Comments

  1. I think it’s also important to be able to print the original page. I often take screenshots just because the print looks totally different to the browser view. If you need to print out the original page, for example for documentation purposes, there should be better ways to taking a screenshot.

  2. My problem with this example is that it shares the same user experiences as the existing (horrible) multi-page printer friendly method. Since it shares the same experience (click on a link, see the page change, print), the user expects to return to the content the same way, by hitting the back button.

    I think you need to build the printer friendly version the same way that you would a good AJAX interface. Finding a way to allow readers to bookmark the page in its current state, as well as allowing them to use the back and forward buttons.

  3. Gary, I totally agree that the back button should always behave as expected. Also not all web designers like that (I’m not sure about the users) I myself would prefer to open to printer friendly view in a new window.

  4. As an author, I’d prefer to ween people off print previews by having the print preview link display a message explaining that the page is already printer friendly.

    But as a user, I like print versions, not for printing, but for reading an article with less crap on the screen.

    As an Opera user, I like print stylesheets even more, because I can easily switch into a print preview mode.

    But I digress – I can see the value of this approach, but also agree on the need for expected Back button behaviour. I didn’t pick up on the “Return to the existing page” link, so I reloaded to get the page “working” again. Other users might have felt they had lost their navigation options.

  5. I like the general idea, but I think the JavaScript is too complicated and it breaks the back button. What I would do is perhaps just to let the “print preview” link go to the same page, but with some ‘flag’ set in the URL that the JavaScript picks up on and thus switches the stylesheet. Perhaps.

    The problem here isn’t really in the technology or the way we develop our sites, but in how little our users know about their browsers. So perhaps the best idea is just to educate them in how they can do print preview and to say that “this page is already printer friendly”? I’ve seen some sites do that; you click the “printer friendly version” link and what you get is just a message that says “hit page is printer friendly” with perhaps a call to ‘window.print()’ afterwards.

    If users just get used to that behaviour instead of the old separate print document behaviour, we won’t need to create solutions like this at all. And that would benefit both users and developers.

  6. Asbjørn, I don’t know about your experience but I gave up on educating users. On our sites we usually have 70% of new users, 30% frequent users. So all you can do is educate 30%. I think you have to find a solution that leads to a resonable soilution for 100% of the users. For me that’s providing a printer frindly view in an extra window, although the original view is already printer friendly. So educated users can print right away, the “normal” users open the printer friendly view and then do the print.

  7. bq. I think the best option is to keep your page clean enough that there is no need for a printer friendly view.

    I disagree with that entirely. Many pages I have written include sidebar navigation. If you don’t have an alternate stylesheet for printing, that takes up a lot of paper, effectively reducing the width of your page by maybe a quarter, which on a longer document could result in needing several additional pages. That’s particularly true on a page with complex navigation.

    Navigation elements that make sense in context make no sense on a printed page, and waste paper and ink. There’s no cost to adding more space or text on screen, which means we can have great fun spreading our webpages all over the place, but there *is* a cost when printing, so most users will want the paper copy to be as concise as possible.

    You also have to consider font style and colour – what is appropriate on the screen is not necessarily ideal on paper. By having a separate stylesheet, you can optimise your page for both media rather than forcing one to be a compromise.

    What I would *like* to do is to educate users to press the _Print Preview_ button if they are concerned about how the document will print, but I don’t think that’s going to be a successful strategy!

  8. bq. I like the general idea, but I think the JavaScript is too complicated and it breaks the back button. What I would do is perhaps just to let the “print preview”? link go to the same page, but with some “˜flag’ set in the URL that the JavaScript picks up on and thus switches the stylesheet. Perhaps.

    What I’ve started to do on some of my pages, which are framed, is to have a “print page” link that is contained within document.write, so that only JS-enabled browsers see the link. Except I’ve now found that Opera won’t print just the selected frame, so I need to figure out a way of hiding the script from Opera!

    But yes, it just calls the print function rather than doing a preview, but that’s (partly) because I’m too lazy to figure out the best way of doing it. I would tend towards going for a new window, which the author can then control the width of (and on my site, release it from the frameset), rather than a replacement _in situ_ as suggested here, because I do think that too many users would find this confusing and disorientating.

  9. I’ve always liked print stylesheets so have tried to use them when possible. I’ve implemented my own technique that is partly based on work that has appeared here at A List Apart. “You can view my technique here”:http://www.angelwatt.com/kendall/ . I have many styles to choose from at the top, and one is for printing. It solves the problem of users wanting to print what they see, but does open other issues. The back button does break (though could fix this), and the print style isn’t offered to those not using JavaScript, but these days most people should have it enabled, though a default style is at least given to non-JavaScript users.

    I don’t think there’s a reasonable 100% solution that solves all issues. It comes down to, why are visitors printing your pages, and how would *most* of them want to see it?

    Nice article by the way.

  10. If browsers evolved to be able to print what I see by giving me a magical check box []Disable Print CSS I would be thrilled. I just get annoyed (like Mark) with having to screenshot the page so I can simply print. Gives me that feeling in my stomach that I get when Word tries to capitalize at random and tell me it can do everything better than me.

    (Although I’m all for Print CSS, they’re great – I just want my check box. And the “Printer-friendly page” link should be buried in the annals of history.)

  11. bq. If browsers evolved to be able to print what I see by giving me a magical check box []Disable Print CSS I would be thrilled. I just get annoyed (like Mark) with having to screenshot the page so I can simply print. Gives me that feeling in my stomach that I get when Word tries to capitalize at random and tell me it can do everything better than me.

    I feel this should be a browser feature, rather than a web author feature. The vast majority of people wouldn’t understand what they were getting, and so could end up making the wrong choice.

  12. Most of you reading this can already do this on your own!

    Heck, I’ll even tell you one way:
    Use Firefox and an extension like Chris Pederick’s Web Developer Extension that allows you to edit CSS on the page on the fly. Simply remove all rules that are “@media print {“¦}” or in a separate print stylesheet and you’ll get your “as is” print state. If you need to do it to multiple pages, make the edited rules “stick” with the appropriate button in said extension.

    Adding a “print as is” button to the browser might be a convenient button for many of us here, but would be unused by 98% of the users out there and I fail to see why browser makers would put it high on their list of “to be added” features. Adding a “print as is” to a website as part of the interface would simply be a no-no (unless it were a designer-developer only site), confusing the vast majority of users.

  13. I came across a great example of how *not* to implement printable pages today. Have a look at the “DfES”:http://www.dfes.gov.uk/14-19/ website and what happens with the various printing options!

    * Normal page has no print stylesheet so prints with sidebars and everything if you just press Ctrl+P

    * “Print version” hyperlink opens a new window, with a reflowed version of the page, that starts off with the two navigation menus and ends with a search box and a third menu. All links are clickable (opening another new window), but the differentiation between main menu and expanded submenu is lost – now it’s just one long list.

    * The stylesheet on the print page sets the width of elements using px, and a font size for body text of “0.75em”.

    I despair.

  14. I came across a great example of how *not* to implement printable pages today. Have a look at the “DfES”:http://www.dfes.gov.uk/14-19/ website and what happens with the various printing options!

    * Normal page has no print stylesheet so prints with sidebars and everything if you just press Ctrl+P

    * “Print version” hyperlink opens a new window, with a reflowed version of the page, that starts off with the two navigation menus and ends with a search box and a third menu. All links are clickable (opening another new window), but the differentiation between main menu and expanded submenu is lost – now it’s just one long list.

    * The stylesheet on the print page sets the width of elements using px, and a font size for body text of “0.75em”.

    I despair.

  15. bq. Heck, I’ll even tell you one way: Use Firefox and an extension like Chris Pederick’s Web Developer Extension that allows you to edit CSS on the page on the fly. Simply remove all rules that are “?@media print {“¦}”? or in a separate print stylesheet and you’ll get your “as is”? print state. If you need to do it to multiple pages, make the edited rules “stick”? with the appropriate button in said extension.

    Great idea, I had forgotten that feature of my favorite toolbar – however the page that had most recently frustrated me does not have the @media print{} in thier css it’s instead in the header as a link rel=”stylesheet” media=”print” …

    Do you have a solution for that I overlooked?

  16. When I click on the Preview-Button in the Mac OS Printer Dialogue, Preview pops up, showing a »Print« button and an »Abort« button. The Document which will be printed is displayed in the foremost window. So why don’t work with some Ajax to create a popup from the pagesource, using the print-stylesheets and serve two buttons to print and abort? It seems to be a better solution than doing something in the background of the print-dialogue.

  17. I’m not sure why anyone would just print a page for documentation. Instead of a print screen you might want to use a screen grab extension in Firefox. Until I upgraded to Firefox 2.0, I used “Screen Grab”:http://andy.5263.org/screengrab/ , but because Screen Grab is not Firefox 2.0 compatible, I’m using “Pearl Crescent Page Saver”:http://pearlcrescent.com/products/pagesaver/ . I’ll have to see how it works.

    I think that using a print style sheet is in the best interests of the user and I don’t think that it should look anything like the page. After all, a printer is not a browser. The print CSS should optimize the page for a printer. If you’ve done that, the user shouldn’t be confused.

    This is an interesting technique though I think that users will expect the back button to send them back to the page. As someone else said here, it might be better to open in a new window or use the query string to tell the page to use the print style sheet. This would allow a user to close the “print” window or use the back button for the link with the print instruction in the query string.

  18. Replying to “No. 18”:http://www.alistapart.com/comments/printtopreview?page=2#18

    bq. “¦ the page that had most recently frustrated me does not have the @media print{} in thier css it’s instead in the header as a link rel=”?stylesheet”? media=”?print”? “¦

    Well, in the case of Chris Pederick’s Web Developer extension, it’s not editable in that way; however, if using that extension it gets even easier: go to the WD tool bar -> CSS -> Disable -> Print Styles. Now print it. Ta da!

  19. It seems like losing the back button is too high a cost to incur given functionality that can be achieved by offering a print preview button or hyperlink leading harmlessly to a new page containing the same content.

  20. would it be an idea to show the page with the print stylesheet as a preview, and then displayin the good ol’ print button in this preview… This way the user can see the preview and print it without knowing about how to print from the browser.

  21. The example shown in the article gives the print dialog immediately, on top of the preview window. I think it would be a bit better to show a preview first, then allow the person to easily print. Flemming’s suggestion above is a good one for this.

    Also, it seems to me that the old familiar link text “printer friendly version” (or something like it) is still in widespread use. I like this because it’s familiar by now, and it doesn’t leave any surprises in store: you know you’re getting a version suitable for printing, and there’s no wondering whether you’ll get a print dialog box, a preview, or both.

  22. As a user (and infrequent web designer) I generally despise print stylesheets. I expect that printing the page I see in front of me will give me the page I see in front of me. If you assume you (as the web designer) know which parts I find redundant, you’ll be wrong often enough to leave a bad taste in my mouth. If I want a dry, content-only page, I would much rather have a “printer-friendly” link (a link that opens in the same window so I can use the Back button), see what I’ll get, and print that.
    I also strongly agree with Nathan Jones above; I use “printer friendly” pages more often to read long articles without all the cruft.
    To sum: give me a printer-friendly link, and keep the print stylesheet as minimal as possible.

  23. I don’t know if this will work, but it’s something I’m contemplating – any suggestions welcome!

    I *will* continue to use a print stylesheet, because despite what a couple of people here have said, my experience is that most people prefer pages to print without “fluff” (menus, ads, etc), nicely filling the page.

    What I would like to do is to add a “view page as it will print” link that shows them a preview – but without having to do any recoding. What I’m thinking is to (using _document.write_, obviously) have a link that opens a new window with target name of “print”, and then use an unobtrusive Javascript to @import (again by _document.write_) the print stylesheet with _media=all_, overriding the screen stylesheet, _if the window has name of “print”_.

    I don’t use server-side scripting or CMS, so short of making a copy of every page linked to the print stylesheet, I can’t think of an easier way of achieving this. The question is … will it work?

  24. bq. would it be an idea to show the page with the print stylesheet as a preview

    I’m not sure exactly what you mean here.

    If you use the “print preview” function of your browser, it will render the page according to the print stylesheet.

    If you mean having a link or widget on the page that will switch to the print stylesheet for screen display, that is one of the things that has been discussed here – and in particular, is exactly what I was talking about in #27. The question is the most effective way to do this.

    If you run a database-driven CMS then it’s probably fairly easy to set up. For static .htm pages, not so easy without loads of Javascript.

  25. I’m trying to find a way to have a “printer friendly” link or button that will switch to an alternate style sheet so that then if the user goes file > print it will print with the alternate style sheet. But at the same time keeping it so if the user goes file > print without clicking “printer friendly” it will print with the default style or print the page “as is”.

    I tried using this example:

    http://www.alistapart.com/articles/alternate/

    But it seems that in IE when you switch to an alternate style sheet and try to print, it prints with no style.

    In this example you have a style with media=print so the user can never print the page “as is”. If you don’t use a print=media style is there a way to print with an alternate style sheet in IE?

  26. I think this example would be fine if the preview opened up in a new window and included an actual print button rather than automatically launching the print dialog. This behavior would mimic the actual user process of printing a page with an initial preview. This is what typical users want and expect.

    I’ve been trying to figure out how to make this example work in this fashion, but I’m not super proficient in JS. Does anybody have any suggestions?

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA

Making Room for Variation

In this excerpt from Expressive Designs Systems, Yesenia Perez-Cruz goes deep on what it takes to create design systems that enables intentional, meaningful variation.
Design