Using CSS to print an HTML webpage nicely


Reading time: 35 minutes

Did you know that we can print and save (as PDF) most web pages? provided printing is not blocked. This can be triggered by CTRL + P key shortcut on Windows.

While printing a webpage is very useful feature but it comes with its own challenges. You need special CSS for your page to handle printing to ensure that the printed page looks good according to your control. We will walk you through it and following it, you will be a master of make any HTML web page to be printed.

In this article, you will learn:

  • How to use CSS to make printing a webpage convenient? along with features like adding page break, hiding particular part from printing and others
  • How to block an user from printing a webpage?
  • A demonstration to clarify the ideas involved

Introduction

In this age of staring at our screens, who prints web pages? This is a valid question, but consider:

  1. Printing travel tickets
  2. Saving a PDF for offline reading
  3. Printing route directions or timetables
  4. Printing receipts for bookkeeping purposes

There are more situations, but printing webpages can be frustrating:

  1. Ink is wasted on unneccesasry backgrounds and images
  2. Advertisements are printed
  3. Link URLs cannot be seen
  4. Sections get cropped or disappear entirely

Most web developers don't spend much time to make the printed webpage accessible. Converting responsive, dynamic webpages to paged paper can be challenging, but CSS print control can be utilised to create a basic stylesheet in a few hours.

Print CSS

@media can be used to specify different styles for different media, ie, one can define different rules for a screen and a printer.
The following piece of code specifies different font families for screen and print, but same font size for the two:

<style type = "text/css">
	@media screen
    {
		p.bodyText { font-family: verdana, arial, sans-serif;}
	}

	@media screen
    {
		p.bodyText { font-family: georgia, times, serif;}
	}

	@media screen, print
    {
		p.bodyText { font-size: 10pt;}
	}
</style>

We can also use the media attribute when linking to an external style sheet:

<link rel = "stylesheet" type = "text/css" media = "print" href = "print.css">

Two separate style sheets can also be kept: one for the screen and the other for the printer. The stylesheet for screen can act as a base for the printer stylesheet. To do this:

<link rel = "stylesheet" type = "text/css" media = "screen" href = "main.css">
    <link rel = "stylesheet" type = "text/css" media = "print" href = "print.css">

The print.css styles will be applied in addition to screen styles when the page is printed.

How to debug page printing feature?

  1. Can be done by using Ctrl+P for a print preview

  2. Chrome Developer Tools offers ways to emulate the print layout:

Chrome Dev Tools -> More Tools -> Rendering -> Change rendering emulation to "print"

Screenshot--946--1
Screenshot--947-

Demo for printing a page

We will cover the basics of print CSS.
You can run this demo locally on your machine. Download the code from here.
We have a simple webpage designed with HTML and CSS:
Screenshot--957-

It currently does not have any print CSS added to it. Thus, the print page looks like (at 50% zoom):
Screenshot--948-

Even though no print CSS has been added to the page, some HTML styles have not been retained like the background colour of the page. This is because, by default, browsers do not print the background colour. Also, the font-family of the text is changed to Times, by default.

Let's add a separate stylesheet for printing:

<link rel="stylesheet" type="text/css" media="print" href="print.css">

How to Remove unneccessary content from printing?

Before proceeding, it is advisable to remove and collapse reduntant content with display:none. Typically, unneccessary sections include headers, footers, images, ads, etc.
Add the following piece of code to do the same:

header, footer, aside, nav, form, iframe, .menu, .hero, .adslot {
    display: none;
}

The page now looks like :
Screenshot--952-

As you can see (or not see :D) the advertisement is no longer visible.

Basic Styling

To format the print page, let's add the following code to print.css:

body {
    margin: 0;
    color: #000;
    background-color: #ffff;
    font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
    line-height: 100%;
    font-size: 15px;
}

This piece of code will overwrite the style as defined by main.css. Our print page now looks like:
Screenshot--951--1

HTML provides a fantastic way to add links: <a> tag . However, while printing, this leads to an issue: one cannot view the URL of the link, thus making it useless. To overcome this, add the following:

a[href*='//']:after {
    content:" (" attr(href) ") ";
}

This makes the URL of the link available after it. Similarly, a[]:before can be used to make URL before the link.
Screenshot--953-

How to Invert and Adjust Images?

Sometimes, it may be important to include images in the printed page. However, try not to use images with dark backgrounds as they waste ink. Instead use filter attribute of CSS to invert and adjust the colours of the image, like so:

.graph{
    filter: invert(100%) hue-rotate(180deg) brightness(120%) contrast(150%);
}

Screenshot--954-

You can also adjust the image size to max-width, so it doesn't bleed off the paper:

.img2{
    max-width: 500px;
}

Screenshot--955-

How to add Page breaks?

You might want to add a page break before or after a particular element. Add the following code to add page break after some element:

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

Screenshot--956-

Note: To avoid page break between certain elements, the following code can be added:

p {
  page-break-inside: avoid;
}

How to Block Page Printing?

Sometimes, you may not want to allow the user print your webpage. In this case, it simple to block printing. Simply add the following code to your print.css, and remove everythign else:

body { display: none; }

This will simply lead to a blank page on printing.
However, this may frustrate the user, making them wonder if their computer has not broken down. To avoid such scenarios, you can add a special message for the user like so:
Add all your code to one div element noprint.
After closing this div, crete another div element like so:

<div id="print">
 <p>This page is intended to be viewed online and may not be printed.</p>
 </div>

Add the following to your print.css

#noprint { display: none; }
#print { display: block; }

Add the following to your main.css

#noprint { display: block; }
#print { display: none; }

Now your printed page will look like:
Screenshot--962-