Optimizing Your Website Structure For Print Using CSS

By  on  

As much as I read articles online, I still print a fair amount of them out. Sometimes I print them to pass on to others, other times to read again when I have more time. Unfortunately a great deal of websites put no effort into providing their content in a printer-friendly fashion. The result of them overlooking the print audience is a great article not being read. If only these writers knew how easy it can be to optimize their site for print and how it can greatly enhance the value of their website.

The secret to creating printable pages is being able to identify and control the "content area(s)" of your website. Most websites are composed of a header, footer, sidebars/subnavigation, and one main content area. Control the content area and most of your work is done. The following are my tips to conquering the print media without changing the integrity of your website.

Create A Stylesheet For Print

Of course you have at least one stylesheet to control the layout of the page and formatting of the content, but do you have a stylesheet to control how your page will look like in print? Add the print style sheet, with the media attribute set to "print", at the end of the list of stylesheets in the header. This will allow you to create custom CSS classes applied only at the time of print. Make sure your structure CSS file is given a media attribute of "all."

<!-- Main stylesheet on top -->
<link rel="stylesheet" type="text/css" href="/global.css" mce_href="/global.css" href="/global.css" mce_href="/global.css" media="all" />
<!-- Print only, on bottom -->
<link rel="stylesheet" type="text/css" href="/print.css" mce_href="/print.css" href="/print.css" mce_href="/print.css" media="print" />

Avoid Unnecessary HTML Tables

As much as I try to steer clear of using tables, there's no way to avoid the occasional <tr><td> experience. Forms are much easier to code when using tables. Tables are also great for...get this...data tables. Other than these two situations, a programmer should try to avoid using table, especially when considering print. Controlling the content area of your website can be extremely challenging when the page structure is trapped in a table.

Know Which Portions Of The Page Don't Have Any Print Value

You know that awesome banner you have at the top of your site? Ditch it. And those ads on the right and left sides of the page? Goodbye. Web visitors print your page because of the content on it, not to see the supporting images on your website. Create a class called no-print and add that class declaration to DIVS, images, and other elements that have no print value:

.no-print		{ display:none; }
<!-- Example -->
<div id="navigation" class="no-print">
	.... <!-- who needs navigation when you're looking at a printed piece? -->
</div>

Use Page Breaks

Page breaks in the browser aren't as reliable as they are in Microsoft Word, especially considering the variable content lengths on dynamically created pages, but when utilized well make all the different in printing your website. The CSS specs don't provide a lot of print flexibility but the page-break-before / page-break-after properties prove to be useful. Page breaks are much more reliable when used with DIV elements instead of table cells.

.page-break	{ page-break-before: always; } /* put this class into your main.css file with "display:none;" */
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce eu felis. Curabitur sit amet magna. Nullam aliquet. Aliquam ut diam...
<div class="page-break"></div>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit....

Size Your Page For Print

Obviously your computer monitor can provide a large amount of width to view a page, but I recommend setting the content area width to 600px (an inch equivalent may be better, but I try to deal with one unit specifically, which is pixels). This ensures that words wont bleed outside the print area. Use this width measurement with the page break DIVs you've created in your stylesheet. After you know the width of your printed content area, adjust the dimensions of content blocks inside the main content area if necessary.

Test!

Like any type of programming, testing is important. Note that if you have a website that serves dynamic data, you wont be able to win all the time but you may be able to figure a scheme to format content well most of the time. Be sure to test in multiple browsers (when creating customer websites, I try to check all "Grade A" browsers).

Modifying your page structure for better print results is probably easier than you think -- at least improving your existing template will be. Check back soon for part two, where we analyze optimizing a website's content for print.

Recent Features

  • By
    5 Awesome New Mozilla Technologies You&#8217;ve Never Heard Of

    My trip to Mozilla Summit 2013 was incredible.  I've spent so much time focusing on my project that I had lost sight of all of the great work Mozillians were putting out.  MozSummit provided the perfect reminder of how brilliant my colleagues are and how much...

  • By
    CSS Filters

    CSS filter support recently landed within WebKit nightlies. CSS filters provide a method for modifying the rendering of a basic DOM element, image, or video. CSS filters allow for blurring, warping, and modifying the color intensity of elements. Let's have...

Incredible Demos

  • By
    jQuery Chosen Plugin

    Without a doubt, my least favorite form element is the SELECT element.  The element is almost unstylable, looks different across platforms, has had inconsistent value access, and disaster that is the result of multiple=true is, well, a disaster.  Needless to say, whenever a developer goes...

  • By
    Web Notifications API

    Every UI framework has the same set of widgets which have become almost essential to modern sites: modals, tooltips, button varieties, and notifications.  One problem I find is each site having their own widget colors, styles, and more -- users don't get a consistent experience.  Apparently the...

Discussion

  1. Found this on digg. Very timely and useful as I am currently working on a project where one of the requirements is a “print only” layout. Thank you!

  2. Maha

    Hi
    I am currently working on printing report. In which html page is used to show my content which is from datatable, the report is like row-columnwise structure. If I select to print the report the page simply breaks as per content in table. Instead to that I add those column headers in second, third, fourth…..page too.
    Pls help me out to solve this..

    Thanks in advance

  3. I am sure, this will help lot of beginners….. thanks for share….

    Cheers,
    Vivek
    [http://www.developersnippets.com]

  4. Sen

    how must i do to hide something using CSS and apply this into IE7

  5. bizkid64

    I’m trying to reproduce a government form in a printer-friendly format. I’m using repeated data from a database, but I need to be able to recreate a header and page numbering at the top of each successive page. Any thoughts on how to do this? Also, is there an easy way to figure out the dimensions (in pixels) of the printable area of a page given paper size and various margins?

    I’ve been searching for an answer on this for days, and your site is the closest I’ve come to finding an answer. Thanks.

  6. Just read three of your articles, after a Google search for using CSS to print name tags. Keep it up, this is good stuff.

    fav’d

  7. Fred

    Does page-break-before: always; not work in Chrome? Can’t seem to get it.

  8. I vowed never to buy any printed material a few months ago and here I am, making effectively a print-only web page. Can’t wait for the future, but in the meantime, thanks for the help.

  9. Daniel R

    Thanks for this great article. I’ve noticed that the print-version of your pages don’t show those annoying page-info headers/footers (that give you the url, the page count, etc). How on earth did you manage to get rid of them?

    • Daniel R

      Reading through your style.css, I could answer my own question. The code snippet below squeezes the headers out of printing scope, and if I apply some sensible padding on the elements on the page itself, I can get a well-formatted print layout without the annoying page info headers/footers. Neat!

      @media print {
        @page { margin: 0.5cm; }
      }
      
  10. universalGlove

    I didn’t read all the comments, so hopefully I’m not duplicating observations.

    I was successfully hiding content for print, until I added two new elements to a page.
    They wouldn’t hide, even though the “no-print” class was applied. No reason I could see for it to not work. Tried in both IE 8 and Firefox 11.0.
    However, both new elements were links – anchor tags made to display as block.
    Once I encased them in a div and applied no-print to the div, they stopped printing.

    Didn’t hide for print (IE8 and FF11):

    TEXT
    

    Successfully hid when printed (IE8 and FF11):

    
    	TEXT
    
    

    So, perhaps there are also issues when trying to hide for print any elements that are inherently inline type elements? or just links for some reason?

    I’ll have to look further and experiment sometime.

    • Stuart

      universalGlove,

      The reason your anchor tags are printing could be that the “display: block” in the screen style is overriding the “display: none” in the print styles.

      Try using a more specific selector in the print styles than you’re using in the screen styles, or if that’s not possible use “display: none !important” in the print styles.

      Stuart

  11. Tomi

    And yet, trying to print this page will show the ads and the comments section with inverted colours… at least make a proper example of your site if you preach about this.

  12. Jelle

    Nice article, though ironically, the comment box isn’t turned off when viewing the printing example for this page.

  13. Neel

    Using above code in my html, it works fine.
    but when i print preview there are many blank pages at the bottom of the page.
    I guess that’s because of page-break-before: always;

    Is there any solution for that ?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!