Responsive design is an approach aimed at creating websites that adjust to different browsers and screen resolutions. Many developers go to great lengths to craft attractive interfaces with fluid content, navigation, and typography, but they neglect to consider how the same layout will look printed on a single sheet of page. It’s easy to forget that people still print Web pages, especially since the advent of mobile devices has completely changed the display landscape, but, in reality, the print experience remains an important part of web design.
Polyglot Programming was recently hired to develop a responsive application for corporate users on a variety of devices. A core feature of this system is the ability to generate reports that contain a number of customizable elements. This, of course, made it impractical to use dynamic server-side pdf generation, because it would have been difficult to manage the time and resource overhead associated with rendering a new pdf after each customization. Additionally, the project posed another interesting challenge: Our customer wanted the reports to look exactly the same — whether viewed on a screen, projector, or in print.
We knew it would be no easy feat to create a solution that would meet both requirements. Some issues to solve were:
* Controlling page size
* Dynamically updating and adding HTML content
* Styling the content
* Adapting interactive SVG-based graphs for print
It took a lot of research, a few nifty hacks, and many hours of testing before we were finally able to produce style sheets that allow users to generate reports, make desired customizations, and print files that exactly match what is displayed on screen. We’ve decided to share some of what we’ve learned in hopes that it helps other developers if asked to create or improve the print styling of responsive websites or web-based applications.
Getting Started
Since this overview is primarily about the process of creating styles that will adjust to the constraints and limitations of print, we won’t go into a lot of detail about responsive design. It is, however, important to recognize the obvious differences between screen and print. First, web pages can scroll horizontally and vertically to accommodate lots of content, whereas a printed page is an 8.5″ x 11″ canvas with margins that reduce the available space even further. This means that content that falls outside of the printing area has to be resized and any unnecessary elements have to be hidden or removed.
Second, web pages are often interactive and dynamic, whereas print is essentially static. Drop down menus, tooltips, and image carousels cannot be recreated, and even ordinary links don’t always translate well to paper. For this reason, it’s best to get rid of navigational elements and enhance inline links with guiding text.
Finally, consider the purpose of a page and the reason why people might print it. For example, a page with driving or recipe directions can be greatly simplified to only display pertinent information in an easy-to-read way.
Steps to Set Up a Print Style Sheet
Using a media query allows you to specify styles that will only be applied when a page is printed. Apply the universal selector (*) to remove background colors and shadowing and reset the default font color to black. While this saves ink and expedites the printing process, it is important to consider how logos and branding elements will appear in grayscale.
@media print {
* {
text-shadow: none !important;
color: #000 !important;
background: transparent !important;
box-shadow: none !important;
}
}
If you wish to maintain background colors or images, you can effectively “force” the browser to do so by using -webkit-print-color-adjust: exact; print-color-adjust: exact;. This is especially handy when you want to turn a web page into a PDF file.
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
The @font-face declaration can be used to specify custom fonts for print use. Keep in mind that most web pages typically use sans serif fonts, whereas serif tends to be a better option for print.
@font-face {
font-family: XXX;
src: url("XXX.eot");
src: local("XXX"),
url("XXX.eot?#iefix") format("embedded-opentype"),
url("XXX.woff") format("woff"),
url("XXX.svg#captureit") format("svg"),
url("XXX.ttf") format("opentype");
}
Next, anchors are underlined to indicate links and anchors and abbreviations are expanded with references. No reference text is shown for images and Javascript links.
a, a:visited { text-decoration: underline; }
a[href]:after { content: " (" attr(href) ")"; }
abbr[title]:after { content: " (" attr(title) ")"; }
a[href^="javascript:"]:after,
a[href^="#"]:after { content: ""; }
Paged media declarations are used to specify that images and table rows are not split into different pages, headings are not separated from subtext, and new pages contain at least three lines of text. Please note that paged media is not yet fully supported in all browsers, so you do have to test whether specific page breaks need to be hard-coded. Table borders are collapsed and row and column backgrounds are set to white.
img {
page-break-inside: avoid;
max-width: 100% !important;
}
h2, h3 { page-break-after: avoid; }
p, h2, h3 {
orphans: 3;
widows: 3;
}
table {
border-collapse: collapse !important;
thead { display: table-header-group; }
tr { page-break-inside: avoid; }
td, th { background: #fff !important; }
}
Finally, any unnecessary page elements, such as headers, footers, or navigation bars are hidden. The @page declaration allows you to specify the exact size of a printable area. You can also use it to create multi-page spreads by including different margin options for covers, index pages, etc.
header, footer { display: none; }
@page { margin: 0.25in; }
}
Leave a Reply