All I Want To Do is Print!
Printing from the web has always been kind of hack. I have yet to find a silver bullet that allows users to manage how they go about printing web content. This post will speak to two pretty decent techniques and what they're good at.
There's Wheat, and There's Chaff
When it comes to printing a web page there's traditionally a small section that you want to print and the rest of the page (navigation, footers, etc...) you could really do without. The following two techniques deal with doing just that, allowing the user to print specific sections that you dictate.
The first technique involves putting a hidden IFrame in the page. When it comes time to print we inject the content we want into the hidden IFrame and call print on the IFrame. This is great because it requires very little effort on our part and we can cherry pick content we want to print.
Consider the following example:
var element = document.getElementById(elementId);
if (element != null && window.frames[iframeId] != null)
var content = "<html><body>"+element.innerHTML+"</body></html>";
alert("Unable to locate print resources, request aborted.");
Then you simply need to throw down a hidden iframe like below:
And then some container that contains your content and a button to call print on the iframe:
<button onclick="printContent('printIframe','printContent1')">Print1 </button>
And there you have it, the ability to print discrete page sections. What's even better is that most of the CSS is honored during the print. The mild issue with this is that because the printing is actually done from the iframe as opposed to the original document, the user is left high and dry should they try to do a print preview from the web. There's also a chance that if your CSS selectors are driven by a hierarchy of html elements (ie p div.content) and you don't include all the html in the hierarchy, it won't get applied during the print.
CSS and the @Media Attribute
Another way to print out from the web is to use the @Media CSS attribute to specify a different set of CSS for the printer. This well supported attribute allows you to apply different CSS to a document if the client is a computer, mobile device, printer, web tv etc... more information can be found here. That is, when the user visits your page a normal set of CSS is used, and when they go to print (or print preview) some additional CSS or an entirely different set of CSS is used, it's your call.
- Add a CSS style that look like this: @media print
- Add a "PrintMe" class to any block of content you want to print: <div class="PrintMe">Printable Content</div>
- It looks at any element that has the class "PrintMe" and adds that same class to all that elements ancestors (parents) and all that elements descendents.
- After that it takes all other elements that don't have this class and puts a "DontPrintMe" class on them.
- Now when the user goes to print, only elements (and their children) that you specifically asked to show in the print will. All others will be hidden (because of the CSS rule we added).
The best thing about this solution is that it's flexible AND it honors the print preview in browsers so users know exactly what's going to be printed. I liked this solution so much that I implemented it in my blog and now all my posts are print/preview savvy.
Wrap it up
During this post we looked at selective printing on the web with two different techniques.
I have to give a special thanks to James Fedor who taught me about the IFrame printing, some of the code you saw in this post is derived from his work.
That's it, hope it helped someone.