The focus of most web developers is designing web content for screen, a category that includes desktops, laptops and mobile devices.
As you progress in web development, it becomes easier to think of styles as modes, a way of viewing a site in different contexts and on different devices. The content of your site is HTML: static, unchanging data. CSS acts as a filter, emphasizing, reducing, eliminating or moving content in a way appropriate to each client. (“Client” in this case meaning the device or software that is interacting with the web page, which may be a television, a printer, or an entertainment unit such as a Wii).
Web developers typically create one stylesheet that is broadly applicable for everything in a site, containing the bulk of the CSS:
<link rel="stylesheet" href="styles.css">
Within the linked stylesheet we create CSS for other devices and clients that are exceptions to the primary rules. Note that we do not have to entirely recreate all the style rules for each new form of media: the primary rules of styles.css will be used in conjunction with any styles that we add, so there is no need to repeat declarations for fonts, etc, unless we choose for them to be different.
The first set of “alternative” rules we are going to create is for the most common device that will interact with our web page, other than screens; it is also the most neglected by web developers. At the bottom of your styles.css page, add this:
@media print {
}
Between the opening and closing curly braces you will be writing the style rules for your pages when they are printed. Again, there is no need to duplicate your earlier rules, only to indicate what is different when a page is printed. There are many possibilities: you could make the printed page appear completely different from the web version, if you wished. Due to the range of options, all I can provide is a list of general suggestions and examples.
- Eliminate site features that are irrelevant to the printed page
- Generally speaking, people don’t print your website to marvel at its use of color or clever accordion menus. If they truly wanted that, they’d use screen capture software to take a snapshot of your page.
When someone prints your site, they are interested in content, and everything else becomes superfluous. Therefore, in the print
@media
query, we turn off the visibility of menu bars, headers, and footers: everything that can’t be used on a printed page, or isn’t relevant to the content.For example, between the curly braces add:
header, footer, nav, aside { display: none; }
This “knocks out” the content within the matching tags when you print the page: the printer acts as if the elements do not exist, while the browser continues to show the website on-screen as the primary CSS rules tells it to.
- Eliminate background images, if used; change colors to high-contrast
- While modern browsers will eliminate background images when printing web pages to improve legibility, older browsers may not. Make sure they do so by setting
background-image: none
in your@media print
rules for elements that have a background image set in styles.css. Similarly, most browsers will change inappropriate color combinations for the purposes of print (white text on a black background converted to black text on white, for example), but older browsers may fail to do so. Assume that your web page is being printed out on a black and white printer, and specify colors appropriately, or use filters to change them. - If measurements are required, use inches, centimeters, points or percentages
- “Pixels” have no relevance to the printed page, and you can usually assume that any printer is using standard paper. Responsive design principles – measuring most elements in percentages or other scalable units – usually works best.
- Expand external hyperlinks to include URL information on the printed page
- Obviously, the reader cannot “click” on the printed page to see where a link goes. However, it is still useful to indicate URL addresses. To do this, we use some advanced CSS in the
@media print
section:a:after { content:" <" attr(href) ">"; }
I’ve shown generated content before; this is simply a variation on the technique. Essentially, the rule says: “immediately after each link, show the value of the link’s
href
attribute when the page is printed.”This works well, but has the drawback of showing URLs for all links, no matter what their destination: internal/local URLs (for navigation within the site) are treated the same as external/remote links. So long as your links are written correctly, we can filter this to show only external links by modifying the declaration to include an attribute selector:
a[href^=http]:after { content:" <" attr(href) ">"; }
Alternatively, if you have used HTML shortcuts for external links:
a[href^=//]:after { content:" <" attr(href) ">"; }
In English, the declaration translates to “so long as the
href
value of the link begins with http or //, print out the URL”. As internal links should be of the format<a href="destination.html">
they will not be printed out, while external links to other sites will be. - Force page breaks where appropriate
- Your printed content will roll down the page as one continuous document, like a chapter from a book. For pages with significant amounts of material, or strongly demarked content, this isn’t always appropriate. For example, you might wish each product presented on the site to be printed on a new page, or a fresh page used for every individual entry on a blog. If you have been consistent in your markup, and use (for the sake of argument) an
h3
element exclusively for each new item, you could write the following within your@media
query:h3 { page-break-before: always; }
This works to ensure that when the printer encounters an
h3
element, it always starts a new page: for all intents and purposes,h3
elements become page headings when printed.The one downside to this approach is that your first page may be essentially blank, or very short, with an
h3
starting the page that follows. One example would be a series of blog articles presented on the same web page, each inside aarticle
element):article + article { page-break-before: always; }
Now the rule states: “start a new page when an article follows another article.” This way the very first article is on the front page, and subsequent articles are on new pages.
- Avoid image breaks across pages
- While browsers will logically split long paragraphs across pages when they are printed, you typically do not want that to occur to images, tables, and other elements. To do so, use
page-break-inside
:img, table { page-break-inside: avoid; }
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.