Stylesheets for Print and Handheld

January 30, 2007

A commenter recently noted that it was difficult to print the Programmer's Bill of Rights post. And he's right. It's high time I set up a print stylesheet for this website. I added the following link tag to the page header:

<link rel="stylesheet" href="/blog/styles-site-print.css"
 type="text/css" media="print" />

The printer-specific CSS is very simple. On a modern site using <div> based layout, optimizing for printers is easy.

  1. Hide named <div>s on the page that aren't relevant to printouts.

    #links {
    display: none;
    }
    
    #searchbox {
    display: none;
    }
    
    #newcomment {
    display: none;
    }
    

  2. Adjust a few margins and widths, and set a default font.

    body {
    margin: 0; padding: 0;
    font-family:calibri, tahoma, arial, sans-serif;
    }
    
    #content {
    width: 100%;
    margin: 0; padding: 0;
    }
    
    #container {
    width: 100%;
    position:relative;
    margin: 0; padding: 0;
    }
    
    .blog {
    padding: 0;
    }
    

The entire printer-friendly CSS file is a mere 35 lines including generous whitespace. Testing the print stylesheet is a piece of cake, too. Just use the File, Print Preview menu:

Coding Horror website in print preview of Internet Explorer 7.0

Looks good to me.

Once you've set up a print stylesheet, you might as well set up a mobile stylesheet, too, because they're almost identical. We just add another link tag to the page header:

<link rel="stylesheet" href="/blog/styles-site-mobile.css"
 type="text/css" media="handheld" />

The CSS is a subset of the printer CSS, so I won't reprint it here. I only hide the links <div>. Testing rendering on a mobile device is a bit more difficult, but it is possible. Here's what it looks like on the new Samsung Blackjack phones we received at work:

Coding Horror website in Pocket IE on the Microsoft SmartPhone 5.0 OS

If you're wondering what your website looks like on a mobile device, wonder no longer. Try it yourself and see. The Windows SmartPhone / PocketPC emulator was surprisingly easy to get up and running. Here's what you'll need:

Once you've downloaded it all, install it in this order:

  1. Install ActiveSync
  2. Unzip and install V1Emulator (standalone_emulator_V1.exe)
  3. Install the Virtual Network Driver (netsvwrap.msi)
  4. Install the Emulator Images for Windows Mobile 5.0 (efp.msi)

I chose to launch the "Smartphone QVGA - Coldboot" emulator. Once it's running, the only tricky part is enabling internet connectivity. This post describes how to enable internet connectivity in the emulator; you place the emulated smartphone in the virtual "cradle" so it can access the network through ActiveSync. Note that you'll also need to set "Allow connections to one of the following" to "DMA" in the File, Connection Settings menu of ActiveSync.

Setting up proper print and handheld stylesheets was fun. And easy. I truly regret not doing it sooner. Don't make the same mistake I did. If you don't have print and handheld stylesheets set up on your website, what are you waiting for?

Posted by Jeff Atwood
41 Comments

It is also possible to see what a website will look like on a handheld device using the "small screen" feature of the Opera browser ( see http://www.opera.com/products/mobile/smallscreen/ ).

Also, the one liner examples appear incorectly in internet explorer (ie adds a vertical scrolling bar). Looks fine in Opera though.

Great site, by the way :)
Keep up the good work.

manu on January 31, 2007 8:51 AM

Is there any way to form a URL that views these styles without actually invoking Print Preview or using the mobile emulator?

Terry on January 31, 2007 9:19 AM

In Firefox you can use the Web Developer extension to switch stylesheets. However, I have found that it produces kinda weird results.. it doesn't use the right font, for example.

Jeff Atwood on January 31, 2007 9:39 AM

Thanks for doing a post on this. It's an important topic which I need to look into.

Chris on January 31, 2007 9:55 AM

Openwave also has a Developer's Network, including SDKs and also, a phone simulator with browser (http://developer.openwave.com/dvl/)

Chris on January 31, 2007 9:58 AM

Also, once you have your nice print css set up, a nice touch is to have a printer icon link like so:

a href="javascript:window.print();"print/a

Some more neat tricks for print css here: http://haacked.com/archive/2006/03/09/ImplementingCSSBasedPrinting.aspx

Haacked on January 31, 2007 11:13 AM

In my (limited) experience, for print you're better off defining your width in 'physical' units - like inches or centimeters. And leave enough lee-way for different browser's default margins. I've had problems with 100% divs printing with the right part of the text 'eaten' by the margin.

Benjol on January 31, 2007 11:43 AM

Nice, printed that very bill myself not long ago ;)
For the print you might consider serif fonts though.

Rimantas on February 1, 2007 2:21 AM

This page looks broken in IE

John Blow on February 1, 2007 3:30 AM

So how do you set/change the font size for print? Some of the time I will need large print, other times not, so it would be useful to be able to do this flexibly. Thank you.

hgs on February 1, 2007 4:45 AM

You can also get device simulators for the BlackBerry:
http://na.blackberry.com/eng/developers/downloads/simulators.jsp

Justin on February 1, 2007 5:42 AM

I was slashdotted once and installed an austere style to reduce bandwidth load. I found it was a much better site for Treos after that. And in some ways, it was a much better site in general :)

Ole Eichhorn on February 1, 2007 6:56 AM

Ole, did the style sheet really affect how browsers downloaded your page? I was always under the impression that the style sheet was basically applied after the rest of the page was downloaded (otherwise how would it know the element ids and classes?)

Reed

Reed Hedges on February 1, 2007 7:52 AM

Reed:

I believe, that since the CSS is loaded in the head of the HTML, it is then loaded into memory. There it is referenced by the HTML when the page loads, producing the visual effects specified.

Chris on February 1, 2007 7:57 AM

Mobile style sheets are great when they work, however you still run into issues where mobile devices don't handle them properly.

I was building a mobile style sheet of a website that needed to be viewed primarily on Blackberries. Turns out I had to create a different set of pages because the Blackberry supported handheld style sheets, but didn't know how to handle the display: none; which is really the most important part.

I hope they fixed this now so I can go back to just using the good CSS to make the web mobile friendly.

Also, a neat trick for print style sheets is to include a high res graphic for the print header. You can hide it in the default screen style sheet, but display it in the print style sheet.

Ryan Smith on February 1, 2007 8:27 AM

Aren't those Blackjack's great? I have one for myself, and I love it.

Nicholas Paldino [.NET/C# MVP] on February 1, 2007 9:44 AM

This page looks broken in IE

It's not specific to IE. I just made the PRE element too large. I cut it in half.

Jeff Atwood on February 1, 2007 9:51 AM

A sort-of related issue: the font on your page looks like crap with ClearType turned off. Maybe you could create a CSS sheet for those of us who prefer not to anti-alias smaller text.

Could I have a different font set than everybody else?

Dan on February 1, 2007 10:12 AM

Dan, I used to resist ClearType too. But then I gave up, because it's inevitable:

http://www.codinghorror.com/blog/archives/000651.html

I do find that as LCDs get cheaper/larger, ClearType is more effective because the "pixels" are smaller and less noticeable.

Jeff Atwood on February 1, 2007 10:36 AM

Great Tip, Thanks!

Balakumar Muthu on February 1, 2007 11:27 AM

One way which i use, is to have a second class called "dontprint", then in my print.css:

.dontprint { display:none; }

So in all my divs which i want to hide, have a second class.

e.g.

div class="logo dontprint"/div

Fiaz on February 1, 2007 11:48 AM

Completely unrelated, but I gotta ask... did you self-author your Google widget, or did someone else make it for you, or did you use the submission tool for URLs?

Jae on February 1, 2007 11:50 AM

Very nice, though I don't think I'll be browsing CodingHorror on my phone. There's a lot of data to download for the front page that's just taken up by past stories I'm not interested in.

[ICR] on February 1, 2007 12:29 PM

Jeff, have you considered excluding comments from print?

Caffenero on February 2, 2007 5:46 AM

Second the post about Opera. So, let's see, you could download a free browser to test this out on mobile devices, or you could do the Microsoft way:


If you're wondering what your website looks like on a mobile device, wonder no longer. Try it yourself and see. The Windows SmartPhone / PocketPC emulator was surprisingly easy to get up and running. Here's what you'll need:

* A clean Windows XP SP2 virtual machine
* The latest version of ActiveSync.
* Standalone Device Emulator with Windows Mobile OS Images (download both items listed here)
* Virtual Machine Network Driver for Microsoft Device Emulator

Once you've downloaded it all, install it in this order:

1. Install ActiveSync
2. Unzip and install V1Emulator (standalone_emulator_V1.exe)
3. Install the Virtual Network Driver (netsvwrap.msi)
4. Install the Emulator Images for Windows Mobile 5.0 (efp.msi)


Yeah. That's easier. Try looking out your window once in a while.

Matt on February 2, 2007 7:01 AM

have you considered excluding comments from print?

I have, but sometimes the discussion in the comments adds significantly to the entry.

I figure if you want the main article only, you can limit the printout to the first 1 or 2 pages.


let's see, you could download a free browser to test this out on mobile devices, or you could do the Microsoft way

Sure, use whatever you want. I personally feel that the best way to test is actually *on* a mobile device (of whatever kind), and the cheapest way to do that is through an emulator.

Jeff Atwood on February 2, 2007 10:20 AM

You could use something like:

.blogbody {page-break-after: always;}

That way comments would always start on a new page.

Nathan on February 3, 2007 11:45 AM

Nathan, great tip! I implemented that on the print stylesheet, and it works a treat.

Jeff Atwood on February 4, 2007 4:17 AM

Ok. thx for nice tutor...

haryx8 on February 8, 2007 2:23 AM

Thanks for the tip - will try it out NOW

Muthu Pillay on February 8, 2007 9:45 AM

thanks for the tip! just finished setting up mine .. it's not perfect .. but it does the job

Thanks again

AL on February 19, 2007 11:52 AM

I wouldn't expect great results from the mobile stylesheet. Many phones, even though they support CSS, won't import an external CSS file (I'm looking at you, Nokia).

Asd on March 8, 2007 7:05 AM

I tend to prefer a single style sheet over a few (as with separate print stlye sheets). A minimal style sheet for printing can then be achieved even easier [1].

[1] http://meiert.com/en/blog/20070221/print-style-sheets-the-basics-for-no-excuses/

Anonymous coward on April 25, 2007 4:43 AM

Thank you very much for the code! I’ve had the code for creating a printer specific CSS and I absolutely love it (I really like being able to make a page that looks great both on the screen and when printed in hard copy). I had no idea the very same code could be used (with a few modifications) to create a page for mobile phones. I’ve never really thought about formatting any of my pages for mobile phones before, but it makes sense. With all of the new phones out there adding more and more web functions and with the internet packages becoming cheaper, more people will be using their phones to surf the net. If you have FireFox, they have some very nice add on packages that let you very quickly and easily change the page to display a site like it would appear on a mobile phone. I downloaded one just for fun, and you’d be amazed at how many sites don’t load on phones.

anonymous on October 12, 2007 1:26 PM

Thanks for this great post, I'll use it!

Online-folder on May 6, 2008 6:11 AM

Perfect! Today I had to do a printer friendly version of several pages. Luckily I came upon this article. I always wondered how this was done. Adding to my toolbox. Nice stuff!

Thanks!!

asp316 on January 5, 2009 12:38 PM

IT is a good idea, I’ve followed you! Keep us updated the best deals!

Sexy costumes on July 14, 2009 7:50 AM

Wow, how sad is it that I'm a web developer and didn't know about this. This is going to save me a lot of time over the next few months!

Aaron G on February 6, 2010 10:03 PM

Great, guy!

Congrats!

Ramon Bispo on February 6, 2010 10:03 PM

I've recently taken the alternate style sheet switcher from A List Apart, at http://www.alistapart.com/articles/alternate/ and modified it to be used with the media attribute instead of the title attribute. I'm working on a website, and at the moment I have 3 links on the page, one to switch to each set of stylesheets. No page reload, no PHP detection of which stylesheet to pass, just a tiny bit of javascript to switch between different media sets. My main purpose for now is debugging without actually constantly opening up a Mobile emulator or Print Preview, but I also plan on using it to create a printer-friendly link, for users who assume that what they see is what's actually going to be printed.

Cliff Gordon on February 6, 2010 10:03 PM

Thanks again for this post. This question came up today, and I knew just where to look.

Jon Galloway on February 6, 2010 10:03 PM

The comments to this entry are closed.