Back To The Future of Print
By now we have weathered the storm that was the early days of web development, a dangerous time when we used tables, inline CSS and separate pages for print only versions. We can reflect in a haggard old sea-dog manner (“yarrr… I remember back in the browser wars…”) on the bad practices of the time. We no longer need convincing that print stylesheets are the way to go1, though some of the documentation for them is a little outdated now.
I am going to briefly cover 8 tips and 4 main gotchas when creating print stylesheets in our more enlightened era.
Getting started
As with regular stylesheets, print CSS can be included in a number of ways2, for our purposes we are going to be using the link
element.
<link rel="stylesheet" type="text/css" media="print" href="print.css">
This is still my favourite way of linking to CSS files, its easy to see what files are being included and to what media they are being applied to. Without the media attribute specified the link element defaults to the media type ‘all’ which means that the styles within then apply to print and screen alike. The media type ‘screen’ only applies to the screen and wont be picked up by print, this is the best way of hiding styles from print.
Make sure you include your print styles after all your other CSS, because you will need to override certain rules and this is a lot easier if you are flowing with the cascade than against it!
Another thing you should be thinking is ‘does it need to be printed’. Consider the context3, if it is not a page that is likely to be printed, such as a landing page or a section index then the print styles should resemble the way the page looks on the screen.
Context is really important for the design of your print stylesheet, all the tips and tricks that follow should be taken in the context of the page. If for example you are designing a print stylesheet for an item in a shopping cart, it is irrelevant for the user to know the exact url of the link that takes them to your checkout.
Tips and tricks
During these tip’s we are going to build up print styles for a textileRef:11112857385470b854b8411:linkStartMarker:“simple
example”:/examples/back-to-the-future-of-print/demo-1.html
1. Remove the cruft
First things first, navigation, headers and most page furniture are pretty much useless and dead space in print so they will need to be removed, using display:none;
.
2. Linearise your content
Content doesn’t work so well in columns in print, especially if the content columns are long and intend to stretch over multiple columns (as mentioned in the gotcha section below). You might want to consider Lineariseing the content to flow down the page. If you have your source order in correct priority this will make things a lot easier4.
3. Improve your type
Once you have removed all the useless cruft and jiggled things about a bit, you can concentrate more on the typography of the page.
Typography is a complex topic5, but simply put serif-ed fonts such as Georgia work better on print and sans serif-ed fonts such as Verdana are more appropriate for screen use. You will probably want to increase font size and line height and change from px
to pt
(which is specifically a print measurement).
4. Go wild on links
There are some incredibly fun things you can do with links in print using CSS. There are two schools of thought, one that consider it is best to disguise inline links as body text because they are not click-able on paper. Personally I believe it is useful to know for reference that the document did link to somewhere originally.
When deciding which approach to take, consider the context of your document, do people need to know where they would have gone to? will it help or hinder them to know this information? Also for an alternative to the below, take a look at Aaron Gustafson’s article on generating footnotes for print6.
Using some clever selector trickery and CSS generated content you can have the location of the link generated after the link itself.
HTML:
<p>I wish <a href="http://www.google.com/">Google</a> could find <a href="/photoOfMyKeys.jpg">my keys</a></p>
CSS:
a:link:after,
a:visited:after,
a:hover:after,
a:active:after {
content: " <" attr(href) "> ";
}
But this is not perfect, in the above example the content of the href
is just naively plonked after the link text:
I wish Google <http://www.google.com/> would find my keys </photoOfMyKeys.jpg>
As looking back over this printout the user is not immediately aware of the location of the link, a better solution is to use even more crazy selectors to deal with relative links. We can also add a style to the generated content so it is distinguishable from the link text itself.
CSS:
a:link:after,
a:visited:after,
a:hover:after,
a:active:after {
content: " <" attr(href) "> ";
color: grey;
font-style: italic;
font-weight: normal;
}
a[href^="/"]:after {
content: " <http://www.example.com"attr(href)"> ";
}
The output is now what we were looking for (you will need to replace example.com with your own root URL):
I wish Google <http://www.google.com/> would find my keys <http://www.example.com/photoOfMyKeys.jpg>
Using regular expressions on the attribute selectors, one final thing you can do is to suppress the generated content on mailto:
links, if for example you know the link text always reflects the email address. Eg:
HTML:
<a href="mailto:[email protected]">[email protected]</a>
CSS:
a[href^="mailto"]:after {
content: "";
}
This example shows the above in action.
Of course with this clever technique, there are the usual browser support issues. While it won’t look as intended in browsers such as Internet Explorer 6 and 7 (IE6 and IE7) it will not break either and will just degrade gracefully because IE cannot do generated content. To the best of my knowledge Safari 2+ and Opera 9.X support a colour set on generated content whereas Firefox 2 & Camino display this in black regardless of the link or inherited text colour.
5. Jazz your headers for print
This is more of a design consideration, don’t go too nuts though; there are a lot more limitations in print media than on screen. For this example we are going to go for is having a bottom border on h2
’s and styling other headings with graduating colors or font sizes.
And here is the example complete with jazzy headers.
6. Build in general hooks
If you are building a large site with many different types of page, you may find it useful to build into your CSS structure, classes that control what is printed (e.g. noprint and printonly). This may not be semantically ideal, but in the past I have found it really useful for maintainability of code across large and varied sites
7. For that extra touch of class
When printing pages from a long URL, even if the option is turned on to show the location of the page in the header, browsers may still display a truncated (and thus useless) version.
Using the above tip (or just simply setting to display:none
in screen and display:block
in print) you can insert the URL of the page you are currently on for print only, using JavaScript’s window.location.href
variable.
function addPrintFooter() {
var p = document.createElement('p');
p.className = 'print-footer';
p.innerHTML = window.location.href;
document.body.appendChild(p);
}
You can then call this function using whichever onload
or ondomready
handler suits your fancy. Here is our familiar demo to show all the above in action
8. Tabular data across pages
If you are using tabled data in your document there are a number of things you can do to increase usability of long tables over several pages. If you use the <thead>
element this should repeat your table headers on the next page should your table be split. You will need to set thead {display: table-header-group;}
explicitly for IE even though this should be the default value.
Also if you use tr {page-break-inside: avoid;}
this should (browser support depending) stop your table row from breaking across two pages. For more information on styling tables for print please see the CSS discuss wiki7.
Gotchas
1. Where did all my content go?
Absolutely the most common mistake I see with print styles is the truncated content bug. The symptom of this is that only the first page of a div
’s content will be printed, the rest will look truncated after this.
Floating long columns may still have this affect, as mentioned in Eric Meyer’s article on ‘A List Apart’ article from 20028; though in testing I am no longer able to replicate this. Using overflow:hidden
on long content in Firefox however still causes this truncation. Overflow hidden is commonly used to clear floats9.
A simple fix can be applied to resolve this, if the column is floated you can override this with float:none
similarly overflow:hidden
can be overridden with overflow:visible
or the offending rules can be banished to a screen only stylesheet.
Using position:absolute
on long columns also has a very similar effect in truncating the content, but can be overridden in print with position:static;
Whilst I only recommend having a print stylesheet for content pages on your site; do at least check other landing pages, section indexes and your homepage. If these are inaccessible in print possibly due to the above gotcha, it might be wise to provide a light dusting of print styles or move the offending overflow / float rules to a screen only stylesheet to fix the issues.
2. Damn those background browser settings
One of the factors of life you now need to accept is that you can’t control the user’s browser settings, no more than you can control whether or not they use IE6. Most browsers by default will not print background colours or images unless explicitly told to by the user.
Naturally this causes a number of problems, for starters you will need to rethink things like branding. At this point it helps if you are doing the print styles early in the project so that you can control the logo not being a background image for example.
Where colour is important to the meaning of the document, for example a status on an invoice, bear in mind that a textural representation will also need to be supplied as the user may be printing in black and white. Borders will print however regardless of setting, so assuming the user is printing in colour you can always use borders to indicate colour.
Check the colour contrast of the text against white, this may need to be altered without backgrounds. You should check how your page looks with backgrounds turned on too, for consistency with the default browser settings you may want to override your background anyway.
One final issue with backgrounds being off is list items. It is relatively common practice to suppress the list-style-type
and replace with a background image to finely control the bullet positioning. This technique doesn’t translate to print, you will need to disable this background bullet and re-instate your trusty friend the list-style-type
.
3. Using JavaScript in your CSS? … beware IE6
Internet explorer has an issue that when Javascript is used in a stylesheet it applies this to all media types even if only applied to screen. For example, if you happen to be using expressions to set a width for IE, perhaps to mimic min-width
, a simple width:100% !important
rule can overcome the effects the expression has on your print styles10.
4. De-enhance your Progressive enhancements
Quite a classic “doh” moment is when you realise that, of course paper doesn’t support Javascript. If you have any dynamic elements on the page, for example a document collapsed per section, you really should have been using Progressive enhancement techniques11 and building for browsers without Javascript first, adding in the fancy stuff later.
If this is the case it should be trivial to override your wizzy JS styles in your print stylesheet, to display all your content and make it accessible for print, which is by far the best method of achieving this affect.
And Finally…
I refer you back to the nature of the document in hand, consider the context of your site and the page. Use the tips here to help you add that extra bit of flair to your printed media.
Be careful you don’t get caught out by the common gotchas, keep the design simple, test cross browser and relish in the medium of print.
Further Reading
1 For more information constantly updated, please see the CSS discuss wiki on print stylesheets
2 For more information on media types and ways of including CSS please refer to the CSS discuss wiki on Media Stylesheets
3 Eric Meyer talks to ThinkVitamin about the importance of context when designing your print strategy.
4 Mark Boulton describes how he applies a newspaper like print stylesheet to an article in the Guardian website. Mark also has some persuasive arguments that print should not be left to last
5 Richard Rutter Has a fantastic resource on typography which also applies to print.
6 Aaron Gustafson has a great solution to link problem by creating footnotes at the end of the page.
7 The CSS discuss wiki has more detailed information on printing tables and detailed browser support
8 This ‘A List Apart’ article is dated May 10th 2002 though is still mostly relevant
9 Float clearing technique using ‘overflow:hidden’
10 Autistic Cuckoo describes the interesting insight with regards to expressions specified for screen in IE6 remaining in print
11 Wikipedia has a good article on the definition of progressive enhancement
12 For a really neat trick involving a dynamically generated column to displaying <abbr>
and <dfn>
meanings (as well as somewhere for the user to write notes), try print previewing on Brian Suda’s site
About the author
Natalie Downe is a Brit living in the Californian sunshine. Her professional experience spans both software engineering and natural history.
After getting a degree in Computer Information Systems from Bath University, she worked with the British Trust for Conservation Volunteers and the Devon Wildlife Trust, then as frontend engineer for Torchbox and Clearleft.
Then whilst travelling the world with her husband Simon Willison, together created Lanyrd which they ran for 3 years and sold to Eventbrite. Natalie transitioned to Director of Frontend Engineering at Eventbrite. In moving herself, her family and her team over to San Francisco, California, Natalie learned more than she wanted to about government buracracy.
Nowadays Natalie works for herself combining her love of nature and web development, occasionally doing public speaking on CSS or Bats (though not at the same time), volunteering for the California Bat Working group, the Marine Mammal Center and assisting the California Acadamy of Science with their tidepool monitoring.
On Sunny days Natalie can be found hiking around the bay area with her husband and her dog Cleo. On rainy days she mostly eats chocolate.