Blog (my web musings)
Find out what's interesting me, get tips, advice, and code gems that don't fit elsewhere.
Search Blog
Print CSS - Setting up a Print Stylesheet
- Details
Back before the days of the interweb-thingy, words were mostly distributed via print… when they weren't being scratched in to bus shelters, or passed from the lips of Aunt Lynn to Nora down the local shops. Print designers crafted their words into neat columns and arty displays at fixed proportions. They worked upon static sheets of paper – a fixed size medium that didn't move or do anything once words were stuck upon it. Design was sure. It was predictable. But then came the web and, along with it, greater possibility. Many of these print designers, swept on the modern tide of technological evolution and poked gently by the potential threat of redundancy, turned their talents to designing for digital screens. Still, circa 2002, the medium was reasonably predictable – the page could get infinitely longer, but the width couldn't stray too far - maybe designing for a resolution of 1024 pixels and no more… because screens didn't go much wider…
But now we have HTML5, smart watches (and smart refrigerators!), massive 3440 x 1440 monitors (thank you Philips BDM3490UC) and web pages are responsive. Its a very different and uncertain landscape.
In 2016, it is all but forgotten that web layouts originated in print design. And most of us don't really think about printing our digital endeavours – we just carry our tablet into the next room to demonstrate a point or discuss an issue. But we shouldn't sweep print under the carpet altogether. Maybe you've been in that position, like I have, when a boss prints out a page of your beautifully crafted website – just because they prefer to write on a physical paper list of the company policies they're currently reviewing – and its presented back to you in all its full and dismally appalling glory. Cringe! But all is not lost. Even though you've just got your head around responsive design, it doesn't mean that print should be neglected, and it isn't too difficult to make your web pages print-ready with a few print-friendly tricks up your sleeve.
Setting up your print stylesheet
1. You can set up a separate CSS file for printing, and link to it from the <head> section of your web page, with a line of code that looks like this;
<link rel="stylesheet" type="text/css" href="/print.css" media="print">
Note the media="print" part that tells the browser when and where to use this CSS (for print only).
2. You can omit the media attribute from your stylesheet link and instead include print styles in your main CSS file, using a print media query;
@media print {
/* print styles here */
}
I prefer option 2 because the extra few lines of CSS don't really justify an extra HTTP request for a separate file.
Deciding what to print
Now that you know the very basics of how to set up print styles, you should first decide what you want to print. Think about your visitors' intentions while they're on your website, and what will be most useful for them to take away – usually this is just the main content. It doesn't make sense to print certain elements, such as fancy headers, footers, navigation, videos and forms (interactive stuff), and some things are just ink drains (hero images) so you can exclude them from print by setting their display property to "none";
@media print {
header, footer, nav, audio, video, embed, object, form { display:none }
}
If you haven't used HTML5 markup, you might need to target elements using CSS classes or IDs instead (hit F12 to open the Developer Toolbar – this browser gem is a true friend when identifying elements);
@media print {
header, footer, nav, audio, video, embed, object, form, #hero, .banners, #menu, .youtube-iframe { display:none }
}
The exception to the "hide navigation" rule is with breadcrumbs. They can actually be quite useful to remind somebody reading a paper print-out of whereabouts in a website the interesting content came from. Make previously hidden elements visible again by setting their display property to "block" (or "inline-block", or "table", depending on what they are);
@media print {
header, footer, nav, audio, video, embed, object, form, #hero, .banners, #menu, .youtube-iframe { display:none }
nav.breadcrumbs { display:block }
}
Images – logo and critical content (no ink-wasting fluff)
You might want to consider hiding all the images in your web layout too, unless they are critical to the content they're illustrating;
@media print {
header, footer, nav, audio, video, embed, object, form, #hero, .banners, #menu, .youtube-iframe, img { display:none }
nav.breadcrumbs, img.illustration { display:block }
}
For images that you do want to include in print, set either a max-width of something like 500px, or 100%, so that they don't overspill the page;
@media print {
article img { max-width:100% !important; page-break-inside:avoid; display:block }
}
To avoid having images split and print across 2 pages, also set them to page-break-inside:avoid;. This only works on block-level elements, hence why I've additionally set the display property to "block", above.
One very useful image however, is your logo. I previously said that you should hide your header, but use your own judgement – if your header is pretty simplistic to begin with, it might be perfectly fine to print as-is. But 2 potential kinks with headers/logos are with image quality and colour. You should be optimising your images for web, so the screen logo image used on your site will probably turn out too grainy in print. It also might be so colourful that it doesn't translate well on a black and white printer (a big possibility since ink is expensive and you can't control how your page with be printed). So prepare a print-quality black and white logo (usually 300dpi) and set about with some sneaky pseudo-element hi-jinx to build a custom print-header for your website. You can do this by setting your print logo as the content in a :before pseudo-element, and the name of your website in a :after pseudo-element. If you're lucky, you might be able to use your actual header element. If not, you can insert a blank div specifically for the purpose – <div class="print-header"></div>;
@media print {
.print-header:before { content:url(print-logo.png); display:inline-block; width:200px; height:200px; vertical-align:middle }
.print-header:after { content:'www.mywebsite.com'; display:inline-block; font-size:24pt }
}
Note that I've used a "pt" (point) unit of measure for the font-size in the print header. Usually, pt is a no-no in web design, but this is for print, so let's use the print-friendly pt measure, which leads us to...
Setting default text – font and colour
Now that we've got the fluff out of the way, let's concentrate on formatting the content for print - the main text blurb that is being taken away. Consider standardising the type-face to make reading easier. Serif fonts are considered decorative, yet their appearance serves a higher purpose – they increase the reading speed and readability of long passages of text because they help the eye to travel across lines of words.
High contrast between text and the paper its printed on also aids readability. Black also prints faster. So we'll make the text black and remove all backgrounds, shadows and filters, and set it to a nice font-size (thinking along the lines of a standard Word document using 12pt, which equates to 16px or 1em – 16px being the default font-size in most browsers). I've used the universal selector to target all page elements in one go (*);
@media print {
body { font-family:Georgia, "Times New Roman", Times, serif; font-size:12pt; line-height:1.7em }
* { background:transparent !important; color:#000 !important; text-shadow:none !important; filter:none !important }
h1 { font-size:18pt }
h2 { font-size:16pt }
h3 { font-size:14pt }
}
Also set the size for your headings/titles. You can use this chart by ReedDesign to convert between ems, pixels and points.
Maximise your print content area
If you have a multi-column layout, chances are that you'll have a width or max-width set on your main content/text area. The paper will naturally limit the content width in print so remove all width customisations and let the printed page flow to its own boundary;
@media print {
article { display:block; width:auto !important; max-width:none !important }
}
Formatting links
I like to set links in a muted blue colour, in a shade that is blue enough to indicated a link when printed via a colour printer, yet grey enough to offer enough differentiation in black and white;
@media print {
a, a:visited { color:#06c !important; text-decoration:none }
}
Now, hyperlinks are no good in print because you can't follow them. Wouldn't it be good if you could somehow print the actual URL alongside? Well, you can, using the attribute selector and an :after pseudo-element;
@media print {
a, a:visited { color:#06c !important; text-decoration:none }
a[href]:after { content:" <"attr(href)">"; font-size:11pt }
}
This will print the contents of an href alongside the hyperlink text, in angle brackets. The text is a slightly smaller 11pt to help make further distinction between an URL and text content.
This works well when the href is an absolute URL, but it isn't very useful when the link is to an internal page – it will just look like <contact-us.htm>. So, what I've got onto the habit of doing is 'rooting' my internal URLs with a slash, so that they are all formatted like this;
<a href="/contact-us.htm">Contact Us</a>
With this change, you can target internal URLs inside your print CSS, and prefix the internal path with an absolute website link, like this;
@media print {
a, a:visited { color:#06c !important; text-decoration:none }
a[href]:after { content:" <"attr(href)">"; font-size:11pt }
a[href^="/"]:after { content:" <http://www.mywebsite.com" attr(href)">"}
}
The resulting link printed alongside internal linked content will now look like <http://www.mywebsite.com/contact-us.htm>. Much more useful on the printed page.
One last thing to cover with links – internal links that have no meaning in print. The links I'm talking about are internal jump links (#) and javascripts. We can nullify them so that they don't print at all;
@media print {
a, a:visited { color:#06c !important; text-decoration:none }
a[href]:after { content:" <"attr(href)">"; font-size:11pt }
a[href^="/"]:after { content:" <http://www.mywebsite.com" attr(href)">" }
a[href^="javascript:"]:after, a[href^="#"]:after { content:"" }
}
Natural page-breaks vs Forced page-breaks
The print CSS above is enough to get your pages looking reasonably good in print, with a few extra tweaks and customisations of your own that will be dependent on your own unique website design. However, sometimes you'll want to force a page break rather than letting the chips fall as they may. Remember that browsers print with their own differences so you'll need to do some testing between them to determine where your content breaks. When you need to, you can create a page break by placing this div in your markup;
<div class="page-break"></div>
And this goes in the print CSS;
@media print {
.page-break { display:block; page-break-before:always }
}
The complete Print CSS starter stylesheet
@media print {
header, footer, nav, audio, video, embed, object, form, #hero, .banners, #menu, .youtube-iframe, img { display:none }
nav.breadcrumbs, img.illustration { display:block }
article img { max-width:100% !important; page-break-inside:avoid; display:block }
.print-header:before { content:url(print-logo.png); display:inline-block; width:200px; height:200px; vertical-align:middle }
.print-header:after { content:'www.mywebsite.com'; display:inline-block; font-size:24pt }
body { font-family:Georgia, "Times New Roman", Times, serif; font-size:12pt; line-height:1.7em }
* { background:transparent !important; color:#000 !important; text-shadow:none !important; filter:none !important }
h1 { font-size:18pt }
h2 { font-size:16pt }
h3 { font-size:14pt }
article { display:block; width:auto !important; max-width:none !important }
a, a:visited { color:#06c !important; text-decoration:none }
a[href]:after { content:" <"attr(href)">"; font-size:11pt }
a[href^="/"]:after { content:" <http://www.mywebsite.com" attr(href)">" }
a[href^="javascript:"]:after, a[href^="#"]:after { content:"" }
.page-break { display:block; page-break-before:always }
}
Signing off
There's a lot to consider when building a website and print is another aspect that could make or break both your reputation and your clients' reputation. Its an often overlooked opportunity to leave a lasting impression on your visitors. Hopefully with the help of the information above, you can make it a good one.
Search Blog
Recent Posts
Popular Posts
Latest Scripts
- Scroll Down Before/ After Effect Image Switcher
- Pop-up Text Message with Entrance Effects
- Log and block email spam IPs w/ PHP + .htaccess
- Responsive CSS3 Blinds Effect Slideshow
- AJAX & PHP 5-Star Rating with Flat File Storage
- Defer YouTube Load until Scrolled-To (Lazy-Load)
- Keyboard Accessible 'Tab-to' Menu (JS)
- Defer Image Load until Scrolled-To (Lazy-Loading)
- Scroll Wide Tables w/ Gradient + Indicator (JS)
- Convert anchors to spans (LinkAdv/ Atto in Moodle)