Print stylesheets tend to be somewhat neglected by web developers, but their presence is often greatly appreciated by users. I’ve previously discussed several best practices when using @media print stylesheets to control what appears when the user decides to print your pages on a color printer, but have not directly addressed concerns with greyscale printers (i.e. most laser printers).

Why Printer Defaults In Browsers Are Sub-Par

When printing a web page with a dark background and white text, most browsers will reverse the color scheme, at least to some degree. For example, taking this HTML:

<header>
	<h1>Tower Corporation</h1>
	<h2>Making the future</h2>
</header>

And combining it with this CSS:

header {
	background: #000;
	color: #fff;
	padding: 1rem;
	font-family: Avenir, Arial, sans-serif;
}

Produces the following result in the browser: Sample of white text on a black background in a web page

And the (almost) inverse result when printed: Sample of printing a web page with white text on a black background

Ti logoYou can see that the result isn’t completely inverted, appearing somewhat washed out; we’ll correct that in the CSS to come.

The browser does not make any color adjustments when printing images. If the graphic is a solid bitmap, as shown to the right (using a logo by Trevor Sutherland):

<header>
	<h1><img src="tower-corporation-logo.png" alt="Tower Corporation Logo" style="float: right">Tower Corporation</h1>
	<h2>Making the future</h2>
</header>

The printer will yield the following result: Typical result of printing a graphic image with a black background

The printed result looks even worse if the logo is an alpha-masked PNG or file: Typical result of printing a graphic image with a transperant background

Using CSS3 Filters To Improve The Results Of Printed Web Pages

While I’ve focused on using CSS filters for display on screens, you can also use them in the context of a print @media query to reverse the colors of logos and other graphics when printing:

@media print  {
	header {
		background: none;
		color: #000;
	}
	header img {
		-webkit-filter: invert(100%);
		filter: invert(100%);
	}
}

The printed result now looks like this: Use of a CSS filter to invert the colors of a printed logo

For Firefox, we need to use the SVG equivalent filter. I’d suggest saving this code as a separate file (invert.svg), although it could also be included in the code of page HTML page:

<svg xmlns="http://www.w3.org/2000/svg">
	<filter id="negative"> 
		<feColorMatrix values="-1  0 0 0 1 
			0 -1 0 0 1 
			0 0 -1 0 1 
			0 0 0 1 0" /> 
	</filter> 
</svg>

Adding the new filter to our CSS:

@media print  {
	header {
		background: none;
		color: #000;
	}
	header img {
		filter: url(inverse.svg#negative);
		-webkit-filter: invert(100%);
		filter: invert(100%);
	}
}

There is a solution for IE9 developed by Lea Verou, albeit a rather tricky one that uses the invert color option in CSS. The code will cause conflicts with the above CSS, so I’d recommend placing it inside a conditional comment:

<!--[if IE 9]>
	<style>
		@media print { 
			header:after {
				content:"";
				display: block;
				height: 1px; width: 1px;
				position: absolute;
				top: 100px;
				right: 100px;
				outline: 100px solid invert;
			} 
		}
	</style>
<![endif]-->

Taking the time and effort to concentrate on these kind of details is one of the hallmarks of both great web design and service, and one that will be greatly appreciated by users.